Skip to content

oldgrowth-games/SumoTree

Repository files navigation

SumoTree

SumoTree is a custom Timber Tree, that uploads your Android logs to SumoLogic.

BETA

This version of SumoTree is currently in beta. It works just fine, and I haven't had any issues with it so far, but I still need to do the following:

  • Write tests
  • Profile it and check for performance issues
  • Package and distribute it so we can just add it as a dependency in our Android projects

SumoLogic Setup

You'll need to set up a new collector in sumo. Here's more information about that https://help.sumologic.com/Manage/Collection

I named mine "Mobile" and set the Source Category to "dev/mobile". This is just the default that Sumo uses, but SumoTree will overwrite it with whatever you set for sumoCategory which is defaulted to "prod/mobile". This is customizable at any time so you can adjust to "dev/mobile", "preprod/mobile", or whatever you name your environments.

Copy the url for your collector. If you didn't set it up, this can be found in Manage Data > Collection. Then to the right of your collector (Mine is named "Mobile"), click Show URL, then click the Copy button. Hang on to this url. You'll want to add it to local.properties for testing, and to your CI variables.

Application Setup

1. SUMO_URL

Add the url you got from the SumoLogic Setup above to local.properties

SUMO_URL="https://endpoint6.collection.us2.sumologic.com/receiver/v1/http/some-really-long-key-here"

Make sure you add this as a CI environment variable as well! Otherwise, SumoTree will only work in local builds.

2. Update Permissions

You probably already have this, but make sure your app can use the internet. Update your AndroidManifest.xml with the following permissions.

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

3. Update app/build.gradle.kt

[OPTIONAL] I always add these functions near the top for easily grabbing build variables

val secretsPropertiesFile = rootProject.file("secrets.properties")
val secretProperties = Properties()
if (secretsPropertiesFile.exists()) {
    // Try reading secrets from file
    secretProperties.load(FileInputStream(secretsPropertiesFile))
} else {
    // Otherwise read from environment variables, this happens in CI
    secretProperties.setProperty("signing_keystore_password", System.getenv("signing_keystore_password"))
    secretProperties.setProperty("signing_key_password", System.getenv("signing_key_password"))
    secretProperties.setProperty("signing_key_alias", System.getenv("signing_key_alias"))
}

val localPropertiesFile = rootProject.file("local.properties")
val localProperties = Properties()
if (localPropertiesFile.exists()) {
    // Try reading local properties from file
    localProperties.load(FileInputStream(localPropertiesFile))
}

fun findPropValue(key: String) : String {
    return (localProperties[key] as? String) ?: "\"${System.getenv(key)}\""
}
fun findSecretPropValue(key: String) : String {
    return (secretProperties[key] as? String) ?: "\"${System.getenv(key)}\""
}

Grab your SUMO_URL

    buildTypes { ... }
    buildTypes.forEach {
        it.buildConfigField("String", "SUMO_URL", findPropValue("SUMO_URL"))
    }

Make sure your app uses a BuildConfig

    buildFeatures {
        ...
        buildConfig = true
    }

Update your dependencies.
Until this gets packaged and distributed, you'll need to copy all the *.kt files into your project, and add the following dependencies. Sorry for the hassle.

    implementation(libs.timber)
    implementation(libs.androidx.work.runtime.ktx)
    implementation(libs.ktor.client.core)
    implementation(libs.ktor.client.cio)
    implementation(libs.ktor.client.encoding)

Plant It

I like to use an Application class to hold my sumoTree, but you could also do it from your MainActivity if you don't like having an Application class for some reason.

class MySuperSweetApplication : Application() {

    lateinit var sumoTree: SumoTree

    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }

        val appName = BuildConfig.APPLICATION_ID.split(".").lastOrNull() ?: "mysupersweetappName"
        val appVersion = BuildConfig.VERSION_NAME
        val buildVersion = "${BuildConfig.VERSION_CODE}"

        sumoTree = SumoTree(
            context = this,
            uploadUrl = BuildConfig.SUMO_URL,
            sumoName = appName,
            additionData = mapOf(
                "appVersion" to appVersion,
                "buildNumber" to buildVersion
            )
        )
        Thread.setDefaultUncaughtExceptionHandler(sumoTree) // capture and send all crash logs
        sumoTree.plant()
    }
}

That's it! Now anything you log will get saved to disk, uploaded periodically, and deleted from disk ater successful upload.

Usage

Because SumoTree uses Timber, all you have to do is call the globally accessible Timber functions.

Timber.d("debug message")
Timber.i("info message")
Timber.w("warning message")
Timber.e("error message")

SumoLogic recommends the data payload have a size, before compression, of 100KB to 1MB. SumoTree will send log files when they reach 500KB, or when an error message is logged. Whichever comes first.

To pass more information simply call trackAdditionalData. Anything you set in here will be included in every log message.

sumoTree.trackAdditionalData(mapOf( "appVersion" to appVersion, "buildNumber" to buildVersion ))

You may have noticed that the constructor allows you to pass this data as well. We added trackAdditionalData incase you wanted to adjust this data throughtout the liecycle of your app.

Querying in SumoLogic

You can query SumoLogic with things like

_sourceCategory="prod/mobile"
_sourceHost="android"
_sourceName="mysupersweetappName"

The log messages will look something like this

{
    "message":"sumotree test",
    "timestamp":"2023-12-19T14:03:01.067-0600",
    "logLevel":"ERROR",
    "thread":"main",
    "tag":"MySuperSweetApplication",
    "appVersion":"1.0",
    "buildNumber":"1"
}

About

A custom Timber Tree, that uploads your Android logs to SumoLogic.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages