diff --git a/.circleci/config.yml b/.circleci/config.yml index 547b0ec..931bf25 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,6 +17,17 @@ jobs: - android/run-tests: test-command: ./gradlew testDebug - android/save-gradle-cache + lint: + executor: + name: android/android-machine + resource-class: large + tag: default + steps: + - checkout + - android/restore-gradle-cache + - run: + name: "Run Spotless" + command: ./gradlew spotlessCheck smoke_test: executor: name: android/android-machine @@ -89,6 +100,8 @@ workflows: jobs: - unit_test: <<: *filters_always + - lint: + <<: *filters_always - smoke_test: <<: *filters_always - publish_maven: @@ -97,6 +110,7 @@ workflows: - java_beeline requires: - unit_test + - lint - smoke_test nightly: triggers: @@ -108,4 +122,5 @@ workflows: - main jobs: - unit_test + - lint - smoke_test diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..617421a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{kt,kts}] +max_line_length = 200 +ktlint_function_naming_ignore_when_annotated_with = Composable +# `java.util.*,kotlinx.android.synthetic.**` is the default value, we add org.junit.Assert for our unit tests +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,org.junit.Assert.* \ No newline at end of file diff --git a/Makefile b/Makefile index c62d40e..bb550df 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,12 @@ build: test: ./gradlew test +lint: + ./gradlew spotlessCheck + +format: + ./gradlew spotlessApply + clean: clean-smoke-tests ./gradlew clean diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 225c41e..e0b85aa 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -5,6 +5,7 @@ plugins { `signing` alias(libs.plugins.android.library) alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.spotless) } android { @@ -17,7 +18,7 @@ android { minCompileSdk = 21 } - buildConfigField("String","HONEYCOMB_DISTRO_VERSION","\"0.0.1-alpha\"") + buildConfigField("String", "HONEYCOMB_DISTRO_VERSION", "\"0.0.1-alpha\"") testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") @@ -30,7 +31,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + "proguard-rules.pro", ) } } @@ -82,56 +83,59 @@ dependencies { androidTestImplementation(libs.opentelemetry.android.agent) } +apply("${project.rootDir}/spotless.gradle") + publishing { publications { - val maven = create("release") { - groupId = "io.honeycomb.android" - artifactId = "honeycomb-opentelemetry-android" - version = "0.0.1-alpha" + val maven = + create("release") { + groupId = "io.honeycomb.android" + artifactId = "honeycomb-opentelemetry-android" + version = "0.0.1-alpha" - afterEvaluate { - from(components["release"]) - } + afterEvaluate { + from(components["release"]) + } - pom { - name = "Honeycomb OpenTelemetry Distribution for Android" - url = "https://github.com/honeycombio/honeycomb-opentelemetry-android" - description = "Honeycomb SDK for configuring OpenTelemetry instrumentation" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "http://www.apache.org/licenses/LICENSE-2.0.txt" + pom { + name = "Honeycomb OpenTelemetry Distribution for Android" + url = "https://github.com/honeycombio/honeycomb-opentelemetry-android" + description = "Honeycomb SDK for configuring OpenTelemetry instrumentation" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" + } } - } - developers { - developer { - id = "Honeycomb" - name = "Honeycomb" - email = "support@honeycomb.io" - organization = "Honeycomb" - organizationUrl = "https://honeycomb.io" + developers { + developer { + id = "Honeycomb" + name = "Honeycomb" + email = "support@honeycomb.io" + organization = "Honeycomb" + organizationUrl = "https://honeycomb.io" + } + } + scm { + url = "https://github.com/honeycombio/honeycomb-opentelemetry-android" + connection = "scm:git:git@github.com:honeycombio/honeycomb-opentelemetry-android.git" + developerConnection = "scm:git:git@github.com:honeycombio/honeycomb-opentelemetry-android.git" } - } - scm { - url = "https://github.com/honeycombio/honeycomb-opentelemetry-android" - connection = "scm:git:git@github.com:honeycombio/honeycomb-opentelemetry-android.git" - developerConnection = "scm:git:git@github.com:honeycombio/honeycomb-opentelemetry-android.git" } } - } signing { val base64key = System.getenv("GPG_BASE64") val pw = System.getenv("GPG_PASSPHRASE") - val key = if (base64key != null && base64key != "") { - String(Base64.getDecoder().decode(base64key)).trim() - } else { - "" - } - + val key = + if (base64key != null && base64key != "") { + String(Base64.getDecoder().decode(base64key)).trim() + } else { + "" + } useInMemoryPgpKeys(key, pw) sign(maven) } } -} \ No newline at end of file +} diff --git a/core/src/androidTest/java/io/honeycomb/opentelemetry/android/HoneycombOptionsInstrumentedTest.kt b/core/src/androidTest/java/io/honeycomb/opentelemetry/android/HoneycombOptionsInstrumentedTest.kt index e45b27f..16003e1 100644 --- a/core/src/androidTest/java/io/honeycomb/opentelemetry/android/HoneycombOptionsInstrumentedTest.kt +++ b/core/src/androidTest/java/io/honeycomb/opentelemetry/android/HoneycombOptionsInstrumentedTest.kt @@ -1,13 +1,11 @@ package io.honeycomb.opentelemetry.android import android.os.Build -import androidx.test.platform.app.InstrumentationRegistry 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 - -import org.junit.Assert.* import kotlin.time.Duration.Companion.seconds @RunWith(AndroidJUnit4::class) @@ -30,7 +28,8 @@ class HoneycombOptionsInstrumentedTest { "service.name" to "unknown_service", "honeycomb.distro.version" to "0.0.1-alpha", "honeycomb.distro.runtime_version" to Build.VERSION.RELEASE, - ), options.resourceAttributes + ), + options.resourceAttributes, ) } diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index f997061..93f1960 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/core/src/main/java/io/honeycomb/opentelemetry/android/Honeycomb.kt b/core/src/main/java/io/honeycomb/opentelemetry/android/Honeycomb.kt index 3dd6496..8c691d6 100644 --- a/core/src/main/java/io/honeycomb/opentelemetry/android/Honeycomb.kt +++ b/core/src/main/java/io/honeycomb/opentelemetry/android/Honeycomb.kt @@ -53,22 +53,26 @@ class Honeycomb { /** * Automatically configures OpenTelemetryRum based on values stored in the app's resources. */ - fun configure(app: Application, options: HoneycombOptions): OpenTelemetryRum { + fun configure( + app: Application, + options: HoneycombOptions, + ): OpenTelemetryRum { val traceExporter = buildSpanExporter(options) val metricsExporter = buildMetricsExporter(options) - val logsExporter = if (options.logsProtocol == OtlpProtocol.GRPC) { - OtlpGrpcLogRecordExporter.builder() - .setEndpoint(options.logsEndpoint) - .setTimeout(options.logsTimeout.toJavaDuration()) - .setHeaders { options.logsHeaders } - .build() - } else { - OtlpHttpLogRecordExporter.builder() - .setEndpoint(options.logsEndpoint) - .setTimeout(options.logsTimeout.toJavaDuration()) - .setHeaders { options.logsHeaders } - .build() - } + val logsExporter = + if (options.logsProtocol == OtlpProtocol.GRPC) { + OtlpGrpcLogRecordExporter.builder() + .setEndpoint(options.logsEndpoint) + .setTimeout(options.logsTimeout.toJavaDuration()) + .setHeaders { options.logsHeaders } + .build() + } else { + OtlpHttpLogRecordExporter.builder() + .setEndpoint(options.logsEndpoint) + .setTimeout(options.logsTimeout.toJavaDuration()) + .setHeaders { options.logsHeaders } + .build() + } val resource = Resource.builder().putAll(createAttributes(options.resourceAttributes)).build() @@ -82,7 +86,10 @@ class Honeycomb { // Normally, uncaught exception traces have no name, so add one. crashInstrumentation.addAttributesExtractor( AttributesExtractor.constant( - AttributeKey.stringKey("name"), "UncaughtException")) + AttributeKey.stringKey("name"), + "UncaughtException", + ), + ) val batchSpanProcessor = BatchSpanProcessor.builder(traceExporter).build() @@ -95,7 +102,7 @@ class Honeycomb { .addMeterProviderCustomizer { builder, _ -> builder.setResource(resource) builder.registerMetricReader( - PeriodicMetricReader.builder(metricsExporter).build() + PeriodicMetricReader.builder(metricsExporter).build(), ) } .addLoggerProviderCustomizer { builder, _ -> @@ -110,55 +117,57 @@ class Honeycomb { } private fun buildSpanExporter(options: HoneycombOptions): SpanExporter { - val traceExporter = if (options.tracesProtocol == OtlpProtocol.GRPC) { - OtlpGrpcSpanExporter.builder() - .setEndpoint(options.tracesEndpoint) - .setTimeout(options.tracesTimeout.toJavaDuration()) - .setHeaders { options.tracesHeaders } - .build() - } else { - OtlpHttpSpanExporter.builder() - .setEndpoint(options.tracesEndpoint) - .setTimeout(options.tracesTimeout.toJavaDuration()) - .setHeaders { options.tracesHeaders } - .build() - } + val traceExporter = + if (options.tracesProtocol == OtlpProtocol.GRPC) { + OtlpGrpcSpanExporter.builder() + .setEndpoint(options.tracesEndpoint) + .setTimeout(options.tracesTimeout.toJavaDuration()) + .setHeaders { options.tracesHeaders } + .build() + } else { + OtlpHttpSpanExporter.builder() + .setEndpoint(options.tracesEndpoint) + .setTimeout(options.tracesTimeout.toJavaDuration()) + .setHeaders { options.tracesHeaders } + .build() + } if (options.debug) { return SpanExporter.composite(traceExporter, OtlpJsonLoggingSpanExporter.create()) } - return traceExporter; + return traceExporter } private fun buildMetricsExporter(options: HoneycombOptions): MetricExporter { - val metricsExporter = if (options.metricsProtocol == OtlpProtocol.GRPC) { - OtlpGrpcMetricExporter.builder() - .setEndpoint(options.metricsEndpoint) - .setTimeout(options.metricsTimeout.toJavaDuration()) - .setHeaders { options.metricsHeaders } - .build() - } else { - OtlpHttpMetricExporter.builder() - .setEndpoint(options.metricsEndpoint) - .setTimeout(options.metricsTimeout.toJavaDuration()) - .setHeaders { options.metricsHeaders } - .build() - } + val metricsExporter = + if (options.metricsProtocol == OtlpProtocol.GRPC) { + OtlpGrpcMetricExporter.builder() + .setEndpoint(options.metricsEndpoint) + .setTimeout(options.metricsTimeout.toJavaDuration()) + .setHeaders { options.metricsHeaders } + .build() + } else { + OtlpHttpMetricExporter.builder() + .setEndpoint(options.metricsEndpoint) + .setTimeout(options.metricsTimeout.toJavaDuration()) + .setHeaders { options.metricsHeaders } + .build() + } if (options.debug) { return CompositeMetricExporter(metricsExporter, OtlpJsonLoggingMetricExporter.create()) } - return metricsExporter; + return metricsExporter } } - private class CompositeMetricExporter(vararg val exporters: MetricExporter): MetricExporter { + private class CompositeMetricExporter(vararg val exporters: MetricExporter) : MetricExporter { override fun getAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality { return try { - exporters.first().getAggregationTemporality(instrumentType); + exporters.first().getAggregationTemporality(instrumentType) } catch (e: NoSuchElementException) { // doesn't really matter - AggregationTemporality.DELTA; + AggregationTemporality.DELTA } } diff --git a/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptions.kt b/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptions.kt index 1cc3741..cfeff41 100644 --- a/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptions.kt +++ b/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptions.kt @@ -56,7 +56,8 @@ private const val OTEL_EXPORTER_OTLP_LOGS_PROTOCOL_KEY = "OTEL_EXPORTER_OTLP_LOG enum class OtlpProtocol { GRPC, HTTP_PROTOBUF, - HTTP_JSON; + HTTP_JSON, + ; companion object { internal fun parse(s: String): OtlpProtocol? { @@ -104,7 +105,7 @@ private fun getHoneycombEndpoint( endpoint: String?, fallback: String, protocol: OtlpProtocol, - suffix: String + suffix: String, ): String { if (endpoint != null) { return endpoint @@ -128,7 +129,6 @@ private fun getHeaders( generalHeaders: Map, signalHeaders: Map, ): Map { - val otlpVersion = io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION val baseHeaders = mapOf("x-otlp-version" to otlpVersion) val signalBaseHeaders = mutableMapOf("x-honeycomb-team" to apiKey) @@ -159,21 +159,17 @@ data class HoneycombOptions( val logsEndpoint: String, val sampleRate: Int, val debug: Boolean, - val serviceName: String, val resourceAttributes: Map, val tracesSampler: String, val tracesSamplerArg: String?, val propagators: String, - val tracesHeaders: Map, val metricsHeaders: Map, val logsHeaders: Map, - val tracesTimeout: Duration, val metricsTimeout: Duration, val logsTimeout: Duration, - val tracesProtocol: OtlpProtocol, val metricsProtocol: OtlpProtocol, val logsProtocol: OtlpProtocol, @@ -222,7 +218,10 @@ data class HoneycombOptions( configureFromSource(source) } - private fun verifyExporter(source: HoneycombOptionsSource, key: String) { + private fun verifyExporter( + source: HoneycombOptionsSource, + key: String, + ) { val exporter = source.getString(key)?.lowercase() ?: "otlp" if (exporter != "otlp") { throw HoneycombException("unsupported exporter $exporter for $key") @@ -433,17 +432,18 @@ data class HoneycombOptions( * resource attributes should never be overwritten by automatic values. So, if there are * two different service names set, this will use the resource attributes version. */ + // Make sure the service name is in the resource attributes. resourceAttributes.putIfAbsent("service.name", serviceName) // The SDK version is generated from build.gradle.kts. resourceAttributes.putIfAbsent( "honeycomb.distro.version", - BuildConfig.HONEYCOMB_DISTRO_VERSION + BuildConfig.HONEYCOMB_DISTRO_VERSION, ) // Use the display version of Android. This is "unknown" when running tests in the JVM. resourceAttributes.putIfAbsent( "honeycomb.distro.runtime_version", - Build.VERSION.RELEASE ?: "unknown" + Build.VERSION.RELEASE ?: "unknown", ) val tracesApiKey = this.tracesApiKey ?: defaultApiKey() @@ -472,24 +472,27 @@ data class HoneycombOptions( this.logsHeaders, ) - val tracesEndpoint = getHoneycombEndpoint( - this.tracesEndpoint, - apiEndpoint, - tracesProtocol ?: protocol, - "v1/traces" - ) - val metricsEndpoint = getHoneycombEndpoint( - this.metricsEndpoint, - apiEndpoint, - metricsProtocol ?: protocol, - "v1/metrics" - ) - val logsEndpoint = getHoneycombEndpoint( - this.logsEndpoint, - apiEndpoint, - logsProtocol ?: protocol, - "v1/logs" - ) + val tracesEndpoint = + getHoneycombEndpoint( + this.tracesEndpoint, + apiEndpoint, + tracesProtocol ?: protocol, + "v1/traces", + ) + val metricsEndpoint = + getHoneycombEndpoint( + this.metricsEndpoint, + apiEndpoint, + metricsProtocol ?: protocol, + "v1/metrics", + ) + val logsEndpoint = + getHoneycombEndpoint( + this.logsEndpoint, + apiEndpoint, + logsProtocol ?: protocol, + "v1/logs", + ) return HoneycombOptions( tracesApiKey, diff --git a/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptionsResourceSource.kt b/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptionsResourceSource.kt index 8dde43d..9d144dd 100644 --- a/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptionsResourceSource.kt +++ b/core/src/main/java/io/honeycomb/opentelemetry/android/HoneycombOptionsResourceSource.kt @@ -7,9 +7,7 @@ import android.content.res.Resources /** * A HoneycombOptionsSource that reads from values resources. */ -// DiscouragedApi is suppressed, because while it's not recommended to get an identifier by its -// string, it's the only way for a library to look up an optional value resource. -@SuppressLint("DiscouragedApi") +@SuppressLint("DiscouragedApi") // suppressed, because while it's not recommended to get an identifier by its string, it's the only way for a library to look up an optional value resource. internal class HoneycombOptionsResourceSource(context: Context) : HoneycombOptionsSource { private val resources: Resources = context.resources private val packageName: String = context.packageName diff --git a/core/src/test/java/io/honeycomb/opentelemetry/android/HoneycombOptionsUnitTest.kt b/core/src/test/java/io/honeycomb/opentelemetry/android/HoneycombOptionsUnitTest.kt index 8743ae7..6cbb6cc 100644 --- a/core/src/test/java/io/honeycomb/opentelemetry/android/HoneycombOptionsUnitTest.kt +++ b/core/src/test/java/io/honeycomb/opentelemetry/android/HoneycombOptionsUnitTest.kt @@ -1,7 +1,7 @@ package io.honeycomb.opentelemetry.android -import org.junit.Test import org.junit.Assert.* +import org.junit.Test import kotlin.time.Duration.Companion.seconds /** @@ -72,10 +72,11 @@ class HoneycombOptionsUnitTest { assertEquals("https://api.honeycomb.io:443/v1/metrics", options.metricsEndpoint) assertEquals("https://api.honeycomb.io:443/v1/logs", options.logsEndpoint) - val expectedHeaders = mapOf( - "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - "x-honeycomb-team" to "key", - ) + val expectedHeaders = + mapOf( + "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, + "x-honeycomb-team" to "key", + ) assertEquals(expectedHeaders, options.tracesHeaders) assertEquals(expectedHeaders, options.metricsHeaders) assertEquals(expectedHeaders, options.logsHeaders) @@ -94,17 +95,18 @@ class HoneycombOptionsUnitTest { @Test fun options_handlesEmptyStrings() { - val data = hashMapOf( - "HONEYCOMB_API_KEY" to "key", - "OTEL_SERVICE_NAME" to "", - "OTEL_RESOURCE_ATTRIBUTES" to "", - "OTEL_TRACES_SAMPLER" to "", - "OTEL_TRACES_SAMPLER_ARG" to "", - "OTEL_PROPAGATORS" to "", - "OTEL_EXPORTER_OTLP_HEADERS" to "", - "OTEL_EXPORTER_OTLP_TIMEOUT" to null, - "OTEL_EXPORTER_OTLP_PROTOCOL" to "", - ) + val data = + hashMapOf( + "HONEYCOMB_API_KEY" to "key", + "OTEL_SERVICE_NAME" to "", + "OTEL_RESOURCE_ATTRIBUTES" to "", + "OTEL_TRACES_SAMPLER" to "", + "OTEL_TRACES_SAMPLER_ARG" to "", + "OTEL_PROPAGATORS" to "", + "OTEL_EXPORTER_OTLP_HEADERS" to "", + "OTEL_EXPORTER_OTLP_TIMEOUT" to null, + "OTEL_EXPORTER_OTLP_PROTOCOL" to "", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals("unknown_service", options.serviceName) @@ -114,7 +116,7 @@ class HoneycombOptionsUnitTest { "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", ), - options.resourceAttributes + options.resourceAttributes, ) assertEquals("parentbased_always_on", options.tracesSampler) @@ -125,10 +127,11 @@ class HoneycombOptionsUnitTest { assertEquals("https://api.honeycomb.io:443/v1/metrics", options.metricsEndpoint) assertEquals("https://api.honeycomb.io:443/v1/logs", options.logsEndpoint) - val expectedHeaders = mapOf( - "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - "x-honeycomb-team" to "key", - ) + val expectedHeaders = + mapOf( + "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, + "x-honeycomb-team" to "key", + ) assertEquals(expectedHeaders, options.tracesHeaders) assertEquals(expectedHeaders, options.metricsHeaders) assertEquals(expectedHeaders, options.logsHeaders) @@ -144,18 +147,19 @@ class HoneycombOptionsUnitTest { @Test fun options_usesFallbacks() { - val data = hashMapOf( - "HONEYCOMB_API_KEY" to "key", - "HONEYCOMB_API_ENDPOINT" to "http://example.com:1234", - "OTEL_SERVICE_NAME" to "service", - "OTEL_RESOURCE_ATTRIBUTES" to "resource=aaa", - "OTEL_TRACES_SAMPLER" to "sampler", - "OTEL_TRACES_SAMPLER_ARG" to "arg", - "OTEL_PROPAGATORS" to "propagators", - "OTEL_EXPORTER_OTLP_HEADERS" to "header=bbb", - "OTEL_EXPORTER_OTLP_TIMEOUT" to 30000, - "OTEL_EXPORTER_OTLP_PROTOCOL" to "http/json", - ) + val data = + hashMapOf( + "HONEYCOMB_API_KEY" to "key", + "HONEYCOMB_API_ENDPOINT" to "http://example.com:1234", + "OTEL_SERVICE_NAME" to "service", + "OTEL_RESOURCE_ATTRIBUTES" to "resource=aaa", + "OTEL_TRACES_SAMPLER" to "sampler", + "OTEL_TRACES_SAMPLER_ARG" to "arg", + "OTEL_PROPAGATORS" to "propagators", + "OTEL_EXPORTER_OTLP_HEADERS" to "header=bbb", + "OTEL_EXPORTER_OTLP_TIMEOUT" to 30000, + "OTEL_EXPORTER_OTLP_PROTOCOL" to "http/json", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals("service", options.serviceName) @@ -166,7 +170,7 @@ class HoneycombOptionsUnitTest { "honeycomb.distro.version" to "0.0.1-alpha", "honeycomb.distro.runtime_version" to "unknown", ), - options.resourceAttributes + options.resourceAttributes, ) assertEquals("sampler", options.tracesSampler) @@ -177,11 +181,12 @@ class HoneycombOptionsUnitTest { assertEquals("http://example.com:1234/v1/metrics", options.metricsEndpoint) assertEquals("http://example.com:1234/v1/logs", options.logsEndpoint) - val expectedHeaders = mapOf( - "header" to "bbb", - "x-honeycomb-team" to "key", - "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ) + val expectedHeaders = + mapOf( + "header" to "bbb", + "x-honeycomb-team" to "key", + "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, + ) assertEquals(expectedHeaders, options.tracesHeaders) assertEquals(expectedHeaders, options.metricsHeaders) assertEquals(expectedHeaders, options.logsHeaders) @@ -197,35 +202,36 @@ class HoneycombOptionsUnitTest { @Test fun options_usesAllValues() { - val data = hashMapOf( - "HONEYCOMB_API_KEY" to "key", - "HONEYCOMB_DATASET" to "dataset", - "HONEYCOMB_METRICS_DATASET" to "metrics", - "HONEYCOMB_TRACES_APIKEY" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "HONEYCOMB_METRICS_APIKEY" to "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - "HONEYCOMB_LOGS_APIKEY" to "cccccccccccccccccccccccccccccccc", - "HONEYCOMB_TRACES_ENDPOINT" to "http://traces.example.com:1234", - "HONEYCOMB_METRICS_ENDPOINT" to "http://metrics.example.com:1234", - "HONEYCOMB_LOGS_ENDPOINT" to "http://logs.example.com:1234", - "SAMPLE_RATE" to 42, - "DEBUG" to true, - "OTEL_SERVICE_NAME" to "service", - "OTEL_RESOURCE_ATTRIBUTES" to "resource=aaa", - "OTEL_TRACES_SAMPLER" to "sampler", - "OTEL_TRACES_SAMPLER_ARG" to "arg", - "OTEL_PROPAGATORS" to "propagators", - "OTEL_EXPORTER_OTLP_TIMEOUT" to 30000, - "OTEL_EXPORTER_OTLP_PROTOCOL" to "http/json", - "OTEL_EXPORTER_OTLP_TRACES_HEADERS" to "header=ttt", - "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT" to 40000, - "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" to "http/json", - "OTEL_EXPORTER_OTLP_METRICS_HEADERS" to "header=mmm", - "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT" to 50000, - "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL" to "http/json", - "OTEL_EXPORTER_OTLP_LOGS_HEADERS" to "header=lll", - "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT" to 60000, - "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL" to "http/json", - ) + val data = + hashMapOf( + "HONEYCOMB_API_KEY" to "key", + "HONEYCOMB_DATASET" to "dataset", + "HONEYCOMB_METRICS_DATASET" to "metrics", + "HONEYCOMB_TRACES_APIKEY" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "HONEYCOMB_METRICS_APIKEY" to "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "HONEYCOMB_LOGS_APIKEY" to "cccccccccccccccccccccccccccccccc", + "HONEYCOMB_TRACES_ENDPOINT" to "http://traces.example.com:1234", + "HONEYCOMB_METRICS_ENDPOINT" to "http://metrics.example.com:1234", + "HONEYCOMB_LOGS_ENDPOINT" to "http://logs.example.com:1234", + "SAMPLE_RATE" to 42, + "DEBUG" to true, + "OTEL_SERVICE_NAME" to "service", + "OTEL_RESOURCE_ATTRIBUTES" to "resource=aaa", + "OTEL_TRACES_SAMPLER" to "sampler", + "OTEL_TRACES_SAMPLER_ARG" to "arg", + "OTEL_PROPAGATORS" to "propagators", + "OTEL_EXPORTER_OTLP_TIMEOUT" to 30000, + "OTEL_EXPORTER_OTLP_PROTOCOL" to "http/json", + "OTEL_EXPORTER_OTLP_TRACES_HEADERS" to "header=ttt", + "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT" to 40000, + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" to "http/json", + "OTEL_EXPORTER_OTLP_METRICS_HEADERS" to "header=mmm", + "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT" to 50000, + "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL" to "http/json", + "OTEL_EXPORTER_OTLP_LOGS_HEADERS" to "header=lll", + "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT" to 60000, + "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL" to "http/json", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals("service", options.serviceName) @@ -235,7 +241,8 @@ class HoneycombOptionsUnitTest { "resource" to "aaa", "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", - ), options.resourceAttributes + ), + options.resourceAttributes, ) assertEquals("sampler", options.tracesSampler) @@ -252,7 +259,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( @@ -260,7 +268,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( @@ -268,7 +277,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "cccccccccccccccccccccccccccccccc", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.logsHeaders + ), + options.logsHeaders, ) assertEquals(40.seconds, options.tracesTimeout) @@ -285,32 +295,33 @@ class HoneycombOptionsUnitTest { @Test fun options_usesSetValues() { - val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) - .setDataset("dataset") - .setMetricsDataset("metrics") - .setTracesApiKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - .setMetricsApiKey("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") - .setLogsApiKey("cccccccccccccccccccccccccccccccc") - .setTracesApiEndpoint("http://traces.example.com:1234") - .setMetricsApiEndpoint("http://metrics.example.com:1234") - .setLogsApiEndpoint("http://logs.example.com:1234") - .setSampleRate(42) - .setDebug(true) - .setServiceName("service") - .setResourceAttributes(mapOf("resource" to "aaa")) - .setTracesSampler("sampler") - .setTracesSamplerArg("arg") - .setPropagators("propagators") - .setTracesTimeout(40.seconds) - .setMetricsTimeout(50.seconds) - .setLogsTimeout(60.seconds) - .setTracesHeaders(mapOf("header" to "ttt")) - .setMetricsHeaders(mapOf("header" to "mmm")) - .setLogsHeaders(mapOf("header" to "lll")) - .setTracesProtocol(OtlpProtocol.HTTP_JSON) - .setMetricsProtocol(OtlpProtocol.HTTP_JSON) - .setLogsProtocol(OtlpProtocol.HTTP_JSON) - .build() + val options = + HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) + .setDataset("dataset") + .setMetricsDataset("metrics") + .setTracesApiKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .setMetricsApiKey("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") + .setLogsApiKey("cccccccccccccccccccccccccccccccc") + .setTracesApiEndpoint("http://traces.example.com:1234") + .setMetricsApiEndpoint("http://metrics.example.com:1234") + .setLogsApiEndpoint("http://logs.example.com:1234") + .setSampleRate(42) + .setDebug(true) + .setServiceName("service") + .setResourceAttributes(mapOf("resource" to "aaa")) + .setTracesSampler("sampler") + .setTracesSamplerArg("arg") + .setPropagators("propagators") + .setTracesTimeout(40.seconds) + .setMetricsTimeout(50.seconds) + .setLogsTimeout(60.seconds) + .setTracesHeaders(mapOf("header" to "ttt")) + .setMetricsHeaders(mapOf("header" to "mmm")) + .setLogsHeaders(mapOf("header" to "lll")) + .setTracesProtocol(OtlpProtocol.HTTP_JSON) + .setMetricsProtocol(OtlpProtocol.HTTP_JSON) + .setLogsProtocol(OtlpProtocol.HTTP_JSON) + .build() assertEquals("service", options.serviceName) assertEquals( @@ -319,7 +330,8 @@ class HoneycombOptionsUnitTest { "resource" to "aaa", "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", - ), options.resourceAttributes + ), + options.resourceAttributes, ) assertEquals("sampler", options.tracesSampler) @@ -336,7 +348,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( @@ -344,7 +357,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( @@ -352,7 +366,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "cccccccccccccccccccccccccccccccc", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.logsHeaders + ), + options.logsHeaders, ) assertEquals(40.seconds, options.tracesTimeout) @@ -369,22 +384,23 @@ class HoneycombOptionsUnitTest { @Test fun options_usesFallbackSetValues() { - val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) - .setDataset("dataset") - .setMetricsDataset("metrics") - .setApiKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - .setApiEndpoint("http://api.example.com:1234") - .setSampleRate(42) - .setDebug(true) - .setServiceName("service") - .setResourceAttributes(mapOf("resource" to "aaa")) - .setTracesSampler("sampler") - .setTracesSamplerArg("arg") - .setPropagators("propagators") - .setTimeout(30.seconds) - .setHeaders(mapOf("header" to "hhh")) - .setProtocol(OtlpProtocol.HTTP_JSON) - .build() + val options = + HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) + .setDataset("dataset") + .setMetricsDataset("metrics") + .setApiKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .setApiEndpoint("http://api.example.com:1234") + .setSampleRate(42) + .setDebug(true) + .setServiceName("service") + .setResourceAttributes(mapOf("resource" to "aaa")) + .setTracesSampler("sampler") + .setTracesSamplerArg("arg") + .setPropagators("propagators") + .setTimeout(30.seconds) + .setHeaders(mapOf("header" to "hhh")) + .setProtocol(OtlpProtocol.HTTP_JSON) + .build() assertEquals("service", options.serviceName) assertEquals( @@ -393,7 +409,8 @@ class HoneycombOptionsUnitTest { "resource" to "aaa", "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", - ), options.resourceAttributes + ), + options.resourceAttributes, ) assertEquals("sampler", options.tracesSampler) @@ -410,7 +427,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( @@ -418,7 +436,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( @@ -426,7 +445,8 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.logsHeaders + ), + options.logsHeaders, ) assertEquals(30.seconds, options.tracesTimeout) @@ -444,11 +464,12 @@ class HoneycombOptionsUnitTest { @Test fun classicKey_causesDatasetHeader() { val key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) - .setDataset("dataset") - .setMetricsDataset("metrics") - .setApiKey(key) - .build() + val options = + HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) + .setDataset("dataset") + .setMetricsDataset("metrics") + .setApiKey(key) + .build() val otlpVersion = io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION assertEquals( @@ -456,32 +477,36 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.logsHeaders + ), + options.logsHeaders, ) } @Test fun ingestClassicKey_causesDatasetHeader() { val key = "hcaic_7890123456789012345678901234567890123456789012345678901234" - val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) - .setDataset("dataset") - .setMetricsDataset("metrics") - .setApiKey(key) - .build() + val options = + HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) + .setDataset("dataset") + .setMetricsDataset("metrics") + .setApiKey(key) + .build() val otlpVersion = io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION assertEquals( @@ -489,52 +514,59 @@ class HoneycombOptionsUnitTest { "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( "x-honeycomb-dataset" to "dataset", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.logsHeaders + ), + options.logsHeaders, ) } @Test fun newKey_precludesDatasetHeader() { val key = "not_classic" - val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) - .setDataset("dataset") - .setMetricsDataset("metrics") - .setApiKey(key) - .build() + val options = + HoneycombOptions.Builder(HoneycombOptionsMapSource(emptyMap())) + .setDataset("dataset") + .setMetricsDataset("metrics") + .setApiKey(key) + .build() val otlpVersion = io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION assertEquals( mapOf( "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.tracesHeaders + ), + options.tracesHeaders, ) assertEquals( mapOf( "x-honeycomb-dataset" to "metrics", "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.metricsHeaders + ), + options.metricsHeaders, ) assertEquals( mapOf( "x-honeycomb-team" to key, "x-otlp-version" to otlpVersion, - ), options.logsHeaders + ), + options.logsHeaders, ) } @@ -546,17 +578,19 @@ class HoneycombOptionsUnitTest { mapOf( "foo" to "bar", "baz" to "123 456", - ), dict + ), + dict, ) } @Test fun options_headersAreMerged() { - val data = mapOf( - "HONEYCOMB_API_KEY" to "key", - "OTEL_EXPORTER_OTLP_HEADERS" to "foo=bar,baz=qux", - "OTEL_EXPORTER_OTLP_TRACES_HEADERS" to "foo=bar2,merged=yes" - ) + val data = + mapOf( + "HONEYCOMB_API_KEY" to "key", + "OTEL_EXPORTER_OTLP_HEADERS" to "foo=bar,baz=qux", + "OTEL_EXPORTER_OTLP_TRACES_HEADERS" to "foo=bar2,merged=yes", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals( mapOf( @@ -565,17 +599,19 @@ class HoneycombOptionsUnitTest { "merged" to "yes", "x-honeycomb-team" to "key", "x-otlp-version" to io.opentelemetry.android.BuildConfig.OTEL_ANDROID_VERSION, - ), options.tracesHeaders + ), + options.tracesHeaders, ) } @Test fun options_serviceNameTakesPrecedence() { - val data = mapOf( - "HONEYCOMB_API_KEY" to "key", - "OTEL_SERVICE_NAME" to "explicit_name", - "OTEL_RESOURCE_ATTRIBUTES" to "service.name=resource_name" - ) + val data = + mapOf( + "HONEYCOMB_API_KEY" to "key", + "OTEL_SERVICE_NAME" to "explicit_name", + "OTEL_RESOURCE_ATTRIBUTES" to "service.name=resource_name", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals("explicit_name", options.serviceName) assertEquals( @@ -583,16 +619,18 @@ class HoneycombOptionsUnitTest { "service.name" to "resource_name", "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", - ), options.resourceAttributes + ), + options.resourceAttributes, ) } @Test fun options_fallsBackToServiceNameFromResourceAttributes() { - val data = mapOf( - "HONEYCOMB_API_KEY" to "key", - "OTEL_RESOURCE_ATTRIBUTES" to "service.name=better" - ) + val data = + mapOf( + "HONEYCOMB_API_KEY" to "key", + "OTEL_RESOURCE_ATTRIBUTES" to "service.name=better", + ) val options = HoneycombOptions.Builder(HoneycombOptionsMapSource(data)).build() assertEquals("better", options.serviceName) assertEquals( @@ -615,18 +653,20 @@ class HoneycombOptionsUnitTest { "service.name" to "unknown_service", "honeycomb.distro.version" to BuildConfig.HONEYCOMB_DISTRO_VERSION, "honeycomb.distro.runtime_version" to "unknown", - ), options.resourceAttributes + ), + options.resourceAttributes, ) } @Test fun options_throwsOnMalformedKeyValueString() { - val source = HoneycombOptionsMapSource( - mapOf( - "HONEYCOMB_API_KEY" to "key", - "data" to "foo=bar,baz" + val source = + HoneycombOptionsMapSource( + mapOf( + "HONEYCOMB_API_KEY" to "key", + "data" to "foo=bar,baz", + ), ) - ) assertThrows(HoneycombException::class.java) { source.getKeyValueList("data") } @@ -634,15 +674,15 @@ class HoneycombOptionsUnitTest { @Test fun options_throwsOnUnsupportedProtocol() { - val source = HoneycombOptionsMapSource( - mapOf( - "HONEYCOMB_API_KEY" to "key", - "OTEL_TRACES_EXPORTER" to "not a protocol" + val source = + HoneycombOptionsMapSource( + mapOf( + "HONEYCOMB_API_KEY" to "key", + "OTEL_TRACES_EXPORTER" to "not a protocol", + ), ) - ) assertThrows(HoneycombException::class.java) { HoneycombOptions.Builder(source).build() } } } - diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 0babc59..3ae1db3 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -1,7 +1,8 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.jetbrains.kotlin.android) - id("net.bytebuddy.byte-buddy-gradle-plugin") version("1.15.5") + alias(libs.plugins.bytebuddy) + alias(libs.plugins.spotless) } android { @@ -26,7 +27,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + "proguard-rules.pro", ) } } @@ -93,4 +94,6 @@ dependencies { implementation(libs.okhttp) implementation(libs.okhttp.library) byteBuddy(libs.okhttp.agent) -} \ No newline at end of file +} + +apply("${project.rootDir}/spotless.gradle") diff --git a/example/src/androidTest/java/io/honeycomb/opentelemetry/android/example/HoneycombSmokeTest.kt b/example/src/androidTest/java/io/honeycomb/opentelemetry/android/example/HoneycombSmokeTest.kt index a85a567..79c99d7 100644 --- a/example/src/androidTest/java/io/honeycomb/opentelemetry/android/example/HoneycombSmokeTest.kt +++ b/example/src/androidTest/java/io/honeycomb/opentelemetry/android/example/HoneycombSmokeTest.kt @@ -4,16 +4,14 @@ import androidx.compose.ui.test.isDisplayed import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry import org.junit.AfterClass - +import org.junit.Assert.assertEquals +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* -import org.junit.Rule - /** * Instrumented test, which will execute on an Android device. * @@ -24,7 +22,8 @@ import org.junit.Rule @RunWith(AndroidJUnit4::class) class HoneycombSmokeTest { companion object { - @AfterClass @JvmStatic fun flush() { + @AfterClass @JvmStatic + fun flush() { val app = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as ExampleApp app.flush() } @@ -76,4 +75,4 @@ class HoneycombSmokeTest { Thread.sleep(1000) rule.onNodeWithText("Normal").performClick() } -} \ No newline at end of file +} diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index ed56377..fbd0da9 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -22,4 +22,4 @@ - \ No newline at end of file + diff --git a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ExampleApp.kt b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ExampleApp.kt index e615fad..20c30ac 100644 --- a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ExampleApp.kt +++ b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ExampleApp.kt @@ -6,7 +6,7 @@ import io.honeycomb.opentelemetry.android.HoneycombOptions import io.opentelemetry.android.OpenTelemetryRum import io.opentelemetry.sdk.OpenTelemetrySdk -class ExampleApp: Application() { +class ExampleApp : Application() { var otelRum: OpenTelemetryRum? = null override fun onCreate() { @@ -14,13 +14,14 @@ class ExampleApp: Application() { // To use this sample app with Honeycomb, change the api key to your own key, and remove // the call to setApiEndpoint. - val options = HoneycombOptions.builder(this) - .setApiKey("test-key") - .setApiEndpoint("http://10.0.2.2:4318") - .setServiceName("android-test") - .setMetricsDataset("android-test-metrics") - .setDebug(true) - .build() + val options = + HoneycombOptions.builder(this) + .setApiKey("test-key") + .setApiEndpoint("http://10.0.2.2:4318") + .setServiceName("android-test") + .setMetricsDataset("android-test-metrics") + .setDebug(true) + .build() otelRum = Honeycomb.configure(this, options) } diff --git a/example/src/main/java/io/honeycomb/opentelemetry/android/example/MainActivity.kt b/example/src/main/java/io/honeycomb/opentelemetry/android/example/MainActivity.kt index 9d9d62e..6177d8a 100644 --- a/example/src/main/java/io/honeycomb/opentelemetry/android/example/MainActivity.kt +++ b/example/src/main/java/io/honeycomb/opentelemetry/android/example/MainActivity.kt @@ -67,7 +67,7 @@ class MainActivity : ComponentActivity() { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Playground( otelRum, - modifier = Modifier.padding(innerPadding) + modifier = Modifier.padding(innerPadding), ) } } @@ -96,22 +96,31 @@ private fun onSendNetworkRequest(setResponse: (str: String) -> Unit) { setResponse("loading...") val client = OkHttpClient.Builder().build() - val request = Request.Builder() - .url("http://10.0.2.2:1080/simple-api") - .headers(Headers.headersOf("content-type", "application/json", "accept", "application/json")) - .build() - val callback = object : Callback { - override fun onFailure(call: Call, e: IOException) { - Log.w(TAG, "OkHttp error response: $e") - setResponse("error: ${e.message}") - } - override fun onResponse(call: Call, response: Response) { - val body = response.body?.string() - Log.w(TAG, "OkHttp response: ${response.code}: ${response.message}, $body") - setResponse("Network Request Succeeded") - response.close() + val request = + Request.Builder() + .url("http://10.0.2.2:1080/simple-api") + .headers(Headers.headersOf("content-type", "application/json", "accept", "application/json")) + .build() + val callback = + object : Callback { + override fun onFailure( + call: Call, + e: IOException, + ) { + Log.w(TAG, "OkHttp error response: $e") + setResponse("error: ${e.message}") + } + + override fun onResponse( + call: Call, + response: Response, + ) { + val body = response.body?.string() + Log.w(TAG, "OkHttp response: ${response.code}: ${response.message}, $body") + setResponse("Network Request Succeeded") + response.close() + } } - } client.newCall(request).enqueue(callback) } @@ -128,64 +137,72 @@ private fun onCrash() { enum class AnimationSpeed(val sleepTime: Long) { NORMAL(0), SLOW(32), - FROZEN(1400) + FROZEN(1400), } @OptIn(ExperimentalMaterial3Api::class) @Composable -fun Playground(otel: OpenTelemetryRum?, modifier: Modifier = Modifier) { +fun Playground( + otel: OpenTelemetryRum?, + modifier: Modifier = Modifier, +) { val networkRequestStatus = remember { mutableStateOf("") } Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.fillMaxSize(), - ) { + ) { Text( - text = "The following components demonstrate\n" + + text = + "The following components demonstrate\n" + "auto-instrumentation features of the\n" + - "Honeycomb Android SDK." + "Honeycomb Android SDK.", ) Spacer(modifier = Modifier.height(50.dp)) // This component is specifically designed to render slowly, // to demonstrate slow render detections. - val angle = rememberInfiniteTransition( - label = "AngleTransition" - ).animateFloat( - initialValue = 0.0f, - targetValue = 360.0f, - animationSpec = infiniteRepeatable( - tween(1000, easing = LinearEasing), - RepeatMode.Restart), - label = "AngleAnimation", - ) + val angle = + rememberInfiniteTransition( + label = "AngleTransition", + ).animateFloat( + initialValue = 0.0f, + targetValue = 360.0f, + animationSpec = + infiniteRepeatable( + tween(1000, easing = LinearEasing), + RepeatMode.Restart, + ), + label = "AngleAnimation", + ) var animationSpeed by remember { mutableStateOf(AnimationSpeed.NORMAL) } Spacer( - modifier = Modifier - .height(100.dp) - .width(100.dp) - .drawBehind { - // This is what makes it slow. - if (animationSpeed.sleepTime > 0) { - Thread.sleep(animationSpeed.sleepTime) - } - drawCircle(color = Color.Gray) - inset(5.dp.toPx()) { - drawCircle(color = Color.Yellow) - val top = Offset(center.x, 0.0f) - rotate(degrees = angle.value) { - drawLine( - color = Color.Gray, - start = top, - end = center, - strokeWidth = 5.dp.toPx() - ) + modifier = + Modifier + .height(100.dp) + .width(100.dp) + .drawBehind { + // This is what makes it slow. + if (animationSpeed.sleepTime > 0) { + Thread.sleep(animationSpeed.sleepTime) } - } - }, + drawCircle(color = Color.Gray) + inset(5.dp.toPx()) { + drawCircle(color = Color.Yellow) + val top = Offset(center.x, 0.0f) + rotate(degrees = angle.value) { + drawLine( + color = Color.Gray, + start = top, + end = center, + strokeWidth = 5.dp.toPx(), + ) + } + } + }, ) SingleChoiceSegmentedButtonRow { SegmentedButton( @@ -249,4 +266,4 @@ fun PlaygroundPreview() { HoneycombOpenTelemetryAndroidTheme { Playground(null) } -} \ No newline at end of file +} diff --git a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Color.kt b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Color.kt index bbe0bd3..f33dea2 100644 --- a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Color.kt +++ b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Color.kt @@ -8,4 +8,4 @@ val Pink80 = Color(0xFFEFB8C8) val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +val Pink40 = Color(0xFF7D5260) diff --git a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Theme.kt b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Theme.kt index 6e29883..fc845fc 100644 --- a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Theme.kt +++ b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Theme.kt @@ -1,6 +1,5 @@ package io.honeycomb.opentelemetry.android.example.ui.theme -import android.app.Activity import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme @@ -11,17 +10,18 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) - -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 +private val DarkColorScheme = + darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80, + ) +private val LightColorScheme = + lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40, /* Other default colors to override background = Color(0xFFFFFBFE), surface = Color(0xFFFFFBFE), @@ -30,29 +30,30 @@ private val LightColorScheme = lightColorScheme( onTertiary = Color.White, onBackground = Color(0xFF1C1B1F), onSurface = Color(0xFF1C1B1F), - */ -) + */ + ) @Composable fun HoneycombOpenTelemetryAndroidTheme( darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ dynamicColor: Boolean = true, - content: @Composable () -> Unit + content: @Composable () -> Unit, ) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } + val colorScheme = + when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } - darkTheme -> DarkColorScheme - else -> LightColorScheme - } + darkTheme -> DarkColorScheme + else -> LightColorScheme + } MaterialTheme( colorScheme = colorScheme, typography = Typography, - content = content + content = content, ) -} \ No newline at end of file +} diff --git a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Type.kt b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Type.kt index 7ad92c0..219b16a 100644 --- a/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Type.kt +++ b/example/src/main/java/io/honeycomb/opentelemetry/android/example/ui/theme/Type.kt @@ -7,14 +7,16 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp // Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) +val Typography = + Typography( + bodyLarge = + TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp, + ), /* Other default text styles to override titleLarge = TextStyle( fontFamily = FontFamily.Default, @@ -30,5 +32,5 @@ val Typography = Typography( lineHeight = 16.sp, letterSpacing = 0.5.sp ) - */ -) \ No newline at end of file + */ + ) diff --git a/example/src/main/res/drawable-v24/ic_launcher_foreground.xml b/example/src/main/res/drawable-v24/ic_launcher_foreground.xml index 2b068d1..7706ab9 100644 --- a/example/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/example/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -27,4 +27,4 @@ android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" android:strokeWidth="1" android:strokeColor="#00000000" /> - \ No newline at end of file + diff --git a/example/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/example/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755..b3e26b4 100644 --- a/example/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/example/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/example/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/example/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 6f3b755..b3e26b4 100644 --- a/example/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/example/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/example/src/main/res/values/colors.xml b/example/src/main/res/values/colors.xml index f8c6127..ca1931b 100644 --- a/example/src/main/res/values/colors.xml +++ b/example/src/main/res/values/colors.xml @@ -7,4 +7,4 @@ #FF018786 #FF000000 #FFFFFFFF - \ No newline at end of file + diff --git a/example/src/main/res/values/strings.xml b/example/src/main/res/values/strings.xml index e6ce2ab..da08bde 100644 --- a/example/src/main/res/values/strings.xml +++ b/example/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ HoneycombExample - \ No newline at end of file + diff --git a/example/src/main/res/values/themes.xml b/example/src/main/res/values/themes.xml index aad244a..538e290 100644 --- a/example/src/main/res/values/themes.xml +++ b/example/src/main/res/values/themes.xml @@ -2,4 +2,4 @@