Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Analytics-Kotlin Bugsnag
# Analytics-Kotlin BugSnag

Add Bugsnag support to your applications via this plugin for [Analytics-Kotlin](https://github.com/segmentio/analytics-kotlin)

Expand All @@ -8,13 +8,30 @@ To install the Segment-bugsnag integration, simply add this line to your gradle
```
implementation 'com.segment.analytics.kotlin.destinations:bugsnag:<latest_version>'
```

Or the following for Kotlin DSL

```
implementation("com.segment.analytics.kotlin.destinations:bugsnag:<latest_version>")
```

Also add the BugSnag Gradle plugin dependency to your Project project level build.gradle.
```
buildscript {
dependencies {
// ...
classpath "com.bugsnag:bugsnag-android-gradle-plugin:7.4.1"
}
}
```
Or the following for Kotlin DSL
```
buildscript {
dependencies {
// ...
classpath("com.bugsnag:bugsnag-android-gradle-plugin:7.4.1")
}
}
```

## Using the Plugin in your App

Open the file where you setup and configure the Analytics-Kotlin library. Add this plugin to the list of imports.
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ buildscript {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0")
classpath("org.jetbrains.kotlin:kotlin-serialization:1.6.0")
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.bugsnag:bugsnag-android-gradle-plugin:7.4.1")
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ dependencies {

// Partner Dependencies
dependencies {
// TODO add your partner deps here
implementation("com.bugsnag:bugsnag-android:5.28.4")
}

// Test Dependencies
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,100 @@
package com.segment.analytics.kotlin.destinations.bugsnag

class BugsnagDestination {
import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.bugsnag.android.Client
import com.segment.analytics.kotlin.android.plugins.AndroidLifecycle
import com.segment.analytics.kotlin.core.*
import com.segment.analytics.kotlin.core.platform.DestinationPlugin
import com.segment.analytics.kotlin.core.platform.Plugin
import com.segment.analytics.kotlin.core.platform.plugins.logger.log
import com.segment.analytics.kotlin.core.utilities.toContent
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject

class BugsnagDestination : DestinationPlugin(), AndroidLifecycle {
companion object {
private const val BUGSNAG_FULL_KEY = "Bugsnag"
private const val VIEWED_EVENT_FORMAT = "Viewed %s Screen"
}
internal var bugsnagSettings: BugsnagSettings? = null

override val key: String = BUGSNAG_FULL_KEY
internal var client: Client? = null

override fun update(settings: Settings, type: Plugin.UpdateType) {
super.update(settings, type)
if (settings.hasIntegrationSettings(this)) {
this.bugsnagSettings =
settings.destinationSettings(key, BugsnagSettings.serializer())
if (type == Plugin.UpdateType.Initial) {
if(bugsnagSettings!=null) {
analytics.log("Client(context, ${bugsnagSettings?.apiKey})")
initializeBugsnagClient()
}
}
}
}

override fun identify(payload: IdentifyEvent): BaseEvent {
val traitsMap = payload.traits.asStringMap()
val email: String = traitsMap["email"] ?: ""
val name: String = traitsMap["name"]?: ""
client?.setUser(payload.userId, email, name)
val userKey = "User"
for((key, value) in traitsMap) {
client?.addMetadata(userKey, key, value)
analytics.log("client!!.addMetadata($userKey, $key, $value)")
}
return payload
}

override fun screen(payload: ScreenEvent): BaseEvent {
leaveBreadcrumb(String.format(VIEWED_EVENT_FORMAT, payload.name))
return payload
}

override fun track(payload: TrackEvent): BaseEvent {
leaveBreadcrumb(payload.event)
return payload
}

override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
super.onActivityCreated(activity, savedInstanceState)
analytics.log("client.context = ${activity?.localClassName}")
client?.context = activity?.localClassName

}

private fun initializeBugsnagClient():Client {
if(client == null) {
client = Client(analytics.configuration.application as Context, bugsnagSettings!!.apiKey)
client!!.context = (analytics.configuration.application as Context).packageName
}
return client!!
}
private fun leaveBreadcrumb(event: String) {
client?.leaveBreadcrumb(event)
analytics.log(" client?.leaveBreadcrumb($event)")
}

fun getUnderlyingInstance(): Client? {
return client
}
}
/**
* Bugsnag Settings data class.
*/
@Serializable
data class BugsnagSettings(
// Bugsnag API key
var apiKey: String,
// Distinguish errors that happen in different stages of app's release process e.g 'production', 'development', etc.
var releaseStage: String,
// Use SSL When Sending Data to Bugsnag, by default enabled in Segment dashboard
var useSSL: Boolean
)
private fun JsonObject.asStringMap(): Map<String, String> = this.mapValues { (_, value) ->
value.toContent().toString()
}