Mobile metrics
Skill almasumdev/awesome-mobile-observability-agent-skills/.github/skills/metrics/mobile-metrics
Agent skills for logging, metrics, tracing, crash reporting, and analytics in mobile apps.
npx -y skills add almasumdev/awesome-mobile-observability-agent-skills --skill mobile-metricsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Define and capture the core mobile RUM SLIs (startup time, jank, ANR, crash, network error rate, battery) with Firebase, Sentry, Datadog, or OTel. Use when setting up client-side performance metrics.
SKILL.md
6.7 KB, as published. Nobody here has run it
Mobile Metrics and Core SLIs
Instructions
Mobile RUM is the metrics tier of observability. Agree on a small set of SLIs, capture them uniformly across platforms, and attribute them to release + device class.
1. The Core SLI Set
| SLI | Definition | Default SLO |
|---|---|---|
| Crash-free sessions | sessions without a fatal crash / total sessions | >= 99.5% |
| Crash-free users | users without a crash / DAU | >= 99.8% |
| ANR rate (Android) | sessions with an ANR / total sessions | <= 0.1% (Play cutoff 0.47%) |
| App hang rate (iOS) | sessions with a hang > 250 ms / total sessions | <= 0.5% |
| Cold start p95 | time from process start to first-draw on a qualifying cold start | <= 2.5 s Android, 1.8 s iOS |
| Warm start p95 | time from resume to first-draw | <= 800 ms |
| Frozen frame rate | frames > 700 ms / total frames | <= 0.1% |
| Slow frame rate | frames > 16 ms / total frames (60 Hz baseline) | <= 5% |
| Network error rate | 5xx + transport errors / total requests on critical endpoints | <= 1% |
| Battery delta per hour fg | mean battery % drop per foreground hour | <= 10% |
Every SLI must be sliceable by release, os_version, device_class (low/mid/high), and country.
2. Source of Truth per SLI
- Crash-free / ANR / hang: Crashlytics or Sentry Release Health. Do not reimplement; consume the vendor metric.
- Cold / warm start: Firebase Performance
_app_starttrace, Sentryapp.start.cold/app.start.warmtransactions, Datadog RUMapplication_start_time. All three are auto-instrumented. - Frozen / slow frames: Android
JankStatslibrary, iOSMetricKitMXAppLaunchMetric/MXCPUMetric, Sentryslow_framesandfrozen_frameson transactions. - Network error rate: HTTP interceptor counter grouped by
endpoint_group(not raw URL -- cardinality). - Battery:
BatteryManageron Android,UIDevice.batteryLevelon iOS, sampled once per foreground minute.
3. Android -- JankStats
class JankReporter(activity: Activity, private val meter: Meter) {
private val stats: JankStats = JankStats.createAndTrack(activity.window) { frame ->
meter.histogramBuilder("mobile.frame.duration")
.setUnit("ms")
.build()
.record(frame.frameDurationUiNanos / 1_000_000.0,
Attributes.of(
AttributeKey.stringKey("screen"), activity.javaClass.simpleName,
AttributeKey.booleanKey("is_jank"), frame.isJank
))
}
fun setTrackingEnabled(enabled: Boolean) { stats.isTrackingEnabled = enabled }
}
4. iOS -- MetricKit
final class MetricsReceiver: NSObject, MXMetricManagerSubscriber {
override init() {
super.init()
MXMetricManager.shared.add(self)
}
func didReceive(_ payloads: [MXMetricPayload]) {
for p in payloads {
if let launch = p.applicationLaunchMetrics {
AppLog.event(logger: "metrics.launch", msg: "launch_metric",
attrs: ["cold_p95_ms": launch.histogrammedTimeToFirstDraw
.bucketEnumerator.allObjects.last as? NSNumber ?? 0])
}
if let hangs = p.applicationResponsivenessMetrics {
AppLog.event(logger: "metrics.hang", msg: "hang_metric",
attrs: ["hang_time_ms": hangs.histogrammedApplicationHangTime])
}
}
}
}
MetricKit delivers once per day on device; do not poll it more often.
5. Flutter -- Firebase Performance
final trace = FirebasePerformance.instance.newTrace('home_feed_load');
await trace.start();
try {
await feedRepo.load();
trace.putAttribute('cache', 'miss');
} finally {
await trace.stop();
}
Automatic traces: _app_start, _app_in_background, _app_in_foreground, plus auto HTTP traces via the firebase_performance HTTP client wrapper. Do not double-instrument.
6. React Native -- Sentry RUM
import { Performance } from '@sentry/react-native';
const t = Sentry.startTransaction({ name: 'home_feed_load', op: 'ui.load' });
try {
await feedRepo.load();
} finally {
t.finish();
}
Hook ReactNavigationInstrumentation into Sentry so every screen transition is a transaction with frame metrics.
7. Cardinality Discipline
Metrics are cheap only when labels are bounded. For every metric:
- Enumerate label values before emitting (
device_class in {low, mid, high}, not raw device model). - Never use
user_id,session_id,request_id, or raw URLs as a label. - Bucket
os_versionto major (16,15,14), not16.4.1. - Cap
screenlabel values to the known screen registry; unknown screens go inscreen="other".
8. Dashboards
A single "Mobile Release Health" dashboard, per release, with these tiles:
- Crash-free sessions & users (trend, 14 days).
- ANR / hang rate by OS version.
- Cold start p50/p75/p95 by device class.
- Frozen frame rate by screen.
- Network error rate by endpoint group.
- Adoption % of current release.
9. Alerts
- SLO burn-rate alert per SLI (see
metric-alertsandalerting-sla). - Release regression alert: any core SLI worse by > 15% vs last released version on the same device class.
- Anomaly alert on sudden drop in session count (could indicate a bootstrap crash hiding the crash signal).
Checklist
- The core SLI set is documented with SLO thresholds and owners.
- Each SLI has a single source of truth, not double-counted across vendors.
- Labels are enumerated; no high-cardinality keys.
- JankStats / MetricKit / Performance SDKs are wired in on their native platforms.
- Every SLI is sliceable by release, os_version, device_class, country.
- Mobile Release Health dashboard exists per platform.
- Release-regression and burn-rate alerts are configured.