Skip to content
4 changes: 4 additions & 0 deletions posthog-android/consumer-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,8 @@
# used in reflection to check if compose is available at runtime
-keepnames class androidx.compose.ui.platform.AndroidComposeView

# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable
Comment on lines +100 to +102
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default this is stripped out from the apk


##---------------End: proguard configuration for okhttp3 ----------
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.posthog.android.internal.PostHogLifecycleObserverIntegration
import com.posthog.android.internal.PostHogSharedPreferences
import com.posthog.android.internal.appContext
import com.posthog.android.internal.getPackageInfo
import com.posthog.android.internal.versionCodeCompat
import com.posthog.android.replay.PostHogReplayIntegration
import com.posthog.android.replay.internal.PostHogLogCatIntegration
import com.posthog.android.surveys.PostHogSurveysIntegration
Expand Down Expand Up @@ -78,13 +79,16 @@ public class PostHogAndroid private constructor() {

val packageInfo = getPackageInfo(context, config)
val packageName = packageInfo?.packageName ?: ""
val versionName = packageInfo?.versionName ?: ""
val buildNumber = packageInfo?.versionCodeCompat() ?: 0L

// only frames coming from the package name will be considered inApp by default
if (packageName.isNotEmpty() && !packageName.startsWith("android.")) {
config.errorTrackingConfig.inAppIncludes.add(packageName)
}

config.context = config.context ?: PostHogAndroidContext(context, config)
val androidContext = config.context ?: PostHogAndroidContext(context, config)
config.context = androidContext

val legacyPath = context.getDir("app_posthog-disk-queue", Context.MODE_PRIVATE)
val path = File(context.cacheDir, "posthog-disk-queue")
Expand All @@ -108,6 +112,10 @@ public class PostHogAndroid private constructor() {
config.sdkVersion = BuildConfig.VERSION_NAME
}

if (config.releaseIdentifier.isNullOrEmpty()) {
config.releaseIdentifier = "$packageName@$versionName+$buildNumber"
}

val mainHandler = MainHandler()
config.addIntegration(PostHogReplayIntegration(context, config, mainHandler))
config.addIntegration(PostHogLogCatIntegration(config))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class DoSomething {
try {
throw MyCustomException("Something went wrong")
} catch (e: Throwable) {
e.stackTraceToString()
PostHog.captureException(e, mapOf("my-custom-error" to true))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ class MyApp : Application() {
sessionReplayConfig.maskAllImages = false
sessionReplayConfig.captureLogcat = true
sessionReplayConfig.screenshot = true
surveys = true
surveys = false
errorTrackingConfig.autoCapture = true
if (!BuildConfig.DEBUG) {
// apps should consider build type and variants
releaseIdentifier = "${BuildConfig.APPLICATION_ID}@${BuildConfig.VERSION_NAME}+${BuildConfig.VERSION_CODE}"
}
}
PostHogAndroid.setup(this, config)
}
Expand Down
1 change: 1 addition & 0 deletions posthog/src/main/java/com/posthog/PostHog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ public class PostHog private constructor(
throwableCoercer.fromThrowableToPostHogProperties(
throwable,
inAppIncludes = config?.errorTrackingConfig?.inAppIncludes ?: listOf(),
releaseIdentifier = config?.releaseIdentifier,
)

properties?.let {
Expand Down
21 changes: 21 additions & 0 deletions posthog/src/main/java/com/posthog/PostHogConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@ public open class PostHogConfig(
* Configuration for PostHog Error Tracking feature.
*/
public val errorTrackingConfig: PostHogErrorTrackingConfig = PostHogErrorTrackingConfig(),

/**
* The release identifier used to identify the correct proguard mappings (mapping.txt)
* in order to make minified stack traces into human readable stack traces
*
* If not set, this will be automatically set to a composed version of your app eg:
* [email protected]+1
* Where:
* 'com.posthog.mobile' is the applicationId
* '1.0.0' is the versionName
* '1' is the versionCode
*
* It can also be a git sha, the hash of the mapping file, etc
* it should be the very same identifier (map-id) used to upload the mapping to the PostHog servers
*
* Soon a Gradle plugin will be provided to do the injection of this identifier automatically
*
* CLI command example:
* posthog-cli exp proguard upload --path "app/build/outputs/mapping/release/mapping.txt" --map-id "[email protected]+1"
*/
public var releaseIdentifier: String? = null,
) {
@PostHogInternal
public var logger: PostHogLogger = PostHogNoOpLogger()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal class ThrowableCoercer {
fun fromThrowableToPostHogProperties(
throwable: Throwable,
inAppIncludes: List<String> = listOf(),
releaseIdentifier: String? = null,
): MutableMap<String, Any> {
val exceptions = mutableListOf<Map<String, Any>>()
val throwableList = mutableListOf<Throwable>()
Expand Down Expand Up @@ -68,6 +69,11 @@ internal class ThrowableCoercer {
myFrame["function"] = frame.methodName
myFrame["platform"] = "java"

// add release identifier for symbolication
if (!releaseIdentifier.isNullOrEmpty()) {
myFrame["map_id"] = releaseIdentifier
}

if (frame.lineNumber >= 0) {
myFrame["lineno"] = frame.lineNumber
}
Expand Down
Loading