Skip to content

Commit

Permalink
Spike demo app (#338)
Browse files Browse the repository at this point in the history
* initial add of sample app

* revert

* rename main app

* placeholder session id

* rename theme

* more naming fixes

* add updated logo images

* hacking on the ui

* hacking on the ui

* cleanup/hacking

* fix endpoint, generate spans on click

* hacking

* cleanup

* add readme notes

* add comment

* spotless and get the build working

* ktlint tweak

* remove items duplicated from conventions

* code review comments

* rename
  • Loading branch information
breedx-splk authored May 7, 2024
1 parent ed5affa commit 125ce67
Show file tree
Hide file tree
Showing 65 changed files with 1,290 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*.{kt,kts}]
ktlint_function_naming_ignore_when_annotated_with=Composable
2 changes: 2 additions & 0 deletions .github/workflows/pr-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
with:
distribution: temurin
java-version: 17
- name: touch local props
run: touch local.properties
- name: run gradle
run: ./gradlew check

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ tasks {

nullaway {
severity.set(CheckSeverity.ERROR)
// Prevent generated binding code in demo app from failing the build
unannotatedSubPackages.add("io.opentelemetry.android.demo.databinding")
}

// Builder 'return this;' pattern
Expand Down
16 changes: 16 additions & 0 deletions demo-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

# OpenTelemetry Android Demo App

This is an app built to demonstrate how to configure and use the OpenTelemetry Android agent
to observe app and user behavior.

This is very much a work in progress.

## Features

* TBD


## How to use

* TBD
72 changes: 72 additions & 0 deletions demo-app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import java.io.FileInputStream
import java.util.Properties

plugins {
id("otel.android-app-conventions")
}

val localProperties = Properties()
localProperties.load(FileInputStream(rootProject.file("local.properties")))

android {
namespace = "io.opentelemetry.android.demo"

defaultConfig {
applicationId = "io.opentelemetry.android.demo"
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
all {
val accessToken = localProperties["rum.access.token"] as String?
resValue("string", "rum_access_token", accessToken ?: "fakebroken")
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
buildFeatures {
compose = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.13"
}
}

dependencies {
implementation(libs.androidx.appcompat)
implementation(libs.androidx.constraintlayout)
implementation(libs.material)
implementation(libs.androidx.lifecycle.livedata.ktx)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.navigation.ui.ktx)
coreLibraryDesugaring(libs.desugarJdkLibs)

implementation(project(":android-agent"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.opentelemetry.sdk)
implementation(libs.opentelemetry.exporter.otlp)
testImplementation(libs.bundles.junit)
androidTestImplementation(libs.androidx.junit)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
Assert.assertEquals("io.opentelemetry.android.demo", appContext.packageName)
}
}
37 changes: 37 additions & 0 deletions demo-app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

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

<application
android:name=".OtelSampleApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".AstronomyShopActivity"
android:exported="true"
android:label="@string/title_activity_astronomy_shop"
/>
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.DemoApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Binary file added demo-app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.opentelemetry.android.demo.databinding.ActivityAstronomyShopBinding

class AstronomyShopActivity : AppCompatActivity() {
private lateinit var binding: ActivityAstronomyShopBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = ActivityAstronomyShopBinding.inflate(layoutInflater)
setContentView(binding.root)

val navView: BottomNavigationView = binding.navView

val navController = findNavController(R.id.nav_host_fragment_activity_astronomy_shop)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration =
AppBarConfiguration(
setOf(
R.id.navigation_home,
R.id.navigation_dashboard,
R.id.navigation_notifications,
),
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
}
54 changes: 54 additions & 0 deletions demo-app/src/main/java/io/opentelemetry/android/demo/CenterText.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp

val gothamFont =
FontFamily(
Font(R.font.gotham_bold, FontWeight.Bold),
)

@Composable
fun CenterText(
text: AnnotatedString,
fontSize: TextUnit = 12.sp,
) {
Text(
text,
textAlign = TextAlign.Center,
fontSize = fontSize,
modifier = Modifier.fillMaxWidth(),
fontFamily = gothamFont,
style = TextStyle.Default.copy(textAlign = TextAlign.Center),
)
}

@Composable
fun CenterText(
text: String,
fontSize: TextUnit = 12.sp,
) {
Text(
text,
textAlign = TextAlign.Center,
fontSize = fontSize,
modifier = Modifier.fillMaxWidth(),
fontFamily = gothamFont,
style = TextStyle.Default.copy(textAlign = TextAlign.Center),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch

class DemoViewModel : ViewModel() {
val sessionIdState = MutableStateFlow("? unknown ?")
private val tracer = OtelSampleApplication.tracer("otel.demo")!!

init {
viewModelScope.launch {
while (true) {
delay(5000)
// TODO: Do some work here maybe
}
}
}

private fun updateSession() {
// TODO
}

private fun sendTrace(
type: String,
value: Float,
) {
// A metric should be a better fit, but for now we're using spans.
tracer.spanBuilder(type).setAttribute("value", value.toDouble()).startSpan().end()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.opentelemetry.android.demo.theme.DemoAppTheme

class MainActivity : ComponentActivity() {
private val viewModel by viewModels<DemoViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DemoAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly,
) {
Row(
Modifier.padding(all = 20.dp),
horizontalArrangement = Arrangement.Center,
) {
CenterText(
fontSize = 40.sp,
text =
buildAnnotatedString {
withStyle(style = SpanStyle(color = Color(0xFFF5A800))) {
append("Open")
}
withStyle(style = SpanStyle(color = Color(0xFF425CC7))) {
append("Telemetry")
}
withStyle(style = SpanStyle(color = Color.Black)) {
append(" Android Demo")
}
toAnnotatedString()
},
)
}
SessionId(viewModel.sessionIdState)
MainOtelButton(
painterResource(id = R.drawable.otel_icon),
)
val context = LocalContext.current
OpenStoreButton(text = "Click to begin", onClick = {
context.startActivity(Intent(this@MainActivity, AstronomyShopActivity::class.java))
})
}
}
}
}
}
}
Loading

0 comments on commit 125ce67

Please sign in to comment.