Measure logo

Logging

Track logs with a severity level, add attributes, and control log collection from the dashboard.

Logs record a plain text message at a severity level. A log is free-form, best for context you'll read back while debugging rather than query precisely. Track one yourself, or turn on automatic collection to capture the logs you already write without touching each call site.

Track a log

Record a message at one of five severities, from debug through fatal, with logDebug, logInfo, logWarning, logError, and logFatal. The severity is what you filter and sort by in the dashboard, so pick the one that matches how much the message should stand out. Bodies longer than 1000 characters are truncated, so lead with the detail you'll search for.

import sh.measure.android.Measure

Measure.logDebug("Cache miss for key user_42")
Measure.logInfo("User signed in")
Measure.logWarning("Payment failed, retrying")
Measure.logError("Checkout request failed")
Measure.logFatal("Unrecoverable database error")
import Measure

Measure.logDebug("Cache miss for key user_42")
Measure.logInfo("User signed in")
Measure.logWarning("Payment failed, retrying")
Measure.logError("Checkout request failed")
Measure.logFatal("Unrecoverable database error")
import 'package:measure_flutter/measure_flutter.dart';

Measure.instance.logDebug("Cache miss for key user_42");
Measure.instance.logInfo("User signed in");
Measure.instance.logWarning("Payment failed, retrying");
Measure.instance.logError("Checkout request failed");
Measure.instance.logFatal("Unrecoverable database error");
import { Measure } from '@measuresh/react-native';

Measure.logDebug({ body: "Cache miss for key user_42" });
Measure.logInfo({ body: "User signed in" });
Measure.logWarning({ body: "Payment failed, retrying" });
Measure.logError({ body: "Checkout request failed" });
Measure.logFatal({ body: "Unrecoverable database error" });
import sh.measure.kmp.Measure

Measure.logDebug("Cache miss for key user_42")
Measure.logInfo("User signed in")
Measure.logWarning("Payment failed, retrying")
Measure.logError("Checkout request failed")
Measure.logFatal("Unrecoverable database error")

A log is free-form text. If you're recording a named thing you'll want to search or chart later, like a user action or feature usage, a custom event is easier to query. To capture an error with its stack trace and grouping, use the handled error APIs rather than logging it by hand.

Add attributes

Attach attributes to a log to record context you can filter on later, like the screen name, an order ID, or a retry count. The extra context is what lets you find one log among thousands.

import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder

val attributes = AttributesBuilder().put("screen", "Checkout").build()
Measure.logWarning("Payment failed", attributes)
import Measure

Measure.logWarning("Payment failed", attributes: ["screen": .string("Checkout")])
import 'package:measure_flutter/measure_flutter.dart';

final attributes = AttributeBuilder().add("screen", "Checkout").build();
Measure.instance.logWarning("Payment failed", attributes: attributes);
import { Measure } from '@measuresh/react-native';

Measure.logWarning({ body: "Payment failed", attributes: { screen: "Checkout" } });
import sh.measure.kmp.Measure
import sh.measure.kmp.attributes.AttributesBuilder

val attributes = AttributesBuilder().put("screen", "Checkout").build()
Measure.logWarning("Payment failed", attributes)

See Attribute limits for the allowed keys and values.

Collect logs automatically

Measure can collect the logs your app already writes, so you don't have to route each one through the SDK by hand. It's off by default. Turn it on with the Automatically collect logs setting in the dashboard, which applies without a new release.

Automatic collection works on Android and React Native only. On iOS and Flutter, bridge your logging framework instead: forward swift-log or the logging package.

Android

Measure instruments android.util.Log at build time, so those calls flow to Measure once you enable the setting. Logs from your own application package are collected by default. To pull in logs from a library or another package, list its prefix with logsAutoCollectPackageNames in your build.gradle.kts. A prefix matches everything under it, so androidx.media3 also covers androidx.media3.exoplayer, androidx.media3.common, and the rest:

measure {
    logsAutoCollectPackageNames = listOf("androidx.media3")
}

React Native

With the setting on, console output (console.debug, console.log, console.info, console.warn, and console.error) is collected on both Android and iOS, with no extra setup.

Configuration options

Control which logs are collected from the dashboard through Adaptive Capture, so you can tune collection without shipping a new build.

OptionDefaultDescription
Automatically collect logsOffCollects the logs your app already writes, see Collect logs automatically. Android and React Native only.
Minimum log levelWarningThe minimum severity to collect. Logs below the selected severity are dropped at the source.
Ignore patterns(empty)Regular expressions matched against the log body. Logs whose body matches any pattern are dropped at the source.

See Adaptive Capture for the full list.

Think this page can be better?

Open an issue