Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Track Exception APIs, and Error Identifier Attributes Span Processor #1172

Open
wants to merge 10 commits into
base: feature/next-gen
Choose a base branch
from

Conversation

tonzhan2
Copy link
Contributor

@tonzhan2 tonzhan2 commented Feb 12, 2025

  • Added trackException and trackException APIs to custom tracking module
  • Added buttons to sample app to test the behavior
  • Add common:utils module which contains the Error Identifier Extractor logic from the splunk-otel-agent
  • Add a Error Identifier Attributes Span Processor to :integration:agent:api module that adds the error identifier attributes to any span that has component = "error" or "crash" (so crashes, ANRs, and custom tracked exceptions)
  • Add some rum constants
  • Add the new span processor when the agent is initialized.

Testing notes
Logged out spans to logcat in AndroidSpanExporter. After clicking test buttons, can see the exception spans generated, with error identifying attributes service.application_id and service.version_code, as well as any additional attributes from calling the trackException API that allows attributes

logs attached:
trackExceptionSpans.txt

@tonzhan2 tonzhan2 marked this pull request as ready for review February 12, 2025 22:56
@tonzhan2 tonzhan2 requested a review from a team as a code owner February 12, 2025 22:56
common/utils/proguard-rules.pro Outdated Show resolved Hide resolved
import io.opentelemetry.sdk.trace.ReadableSpan
import io.opentelemetry.sdk.trace.SpanProcessor

internal class ErrorIdentifierAttributesSpanProcessor(private val application: Application) : SpanProcessor {

Choose a reason for hiding this comment

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

Class named ErrorIdentifierAttributesSpanProcessor adds applicationId, versionCode, customUUID. There is no any error. Please consider of using GlobalAttributeSpanProcessor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The application ID, version code, and uuid (if the customer adds it) only need to be added to crash and error spans that have stacktraces. This is because these attributes are used to correlate an android stacktrace with the correct mapping file for deobfuscation in the backend.

They do not need to be added to any other spans, as they are only relevant to identifying errors. That is why this class is called Error Identifier Attributes Span Processor, its the span processor that adds the attributes that help identify error spans for the backend and is only added to error and crash spans

import android.os.Build
import android.util.Log

class ErrorIdentifierExtractor(private val application: Application) {

Choose a reason for hiding this comment

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

Class named ErrorIdentifierExtractor provides applicationId, versionCode, customUUID. There is no any error.

Copy link
Contributor Author

@tonzhan2 tonzhan2 Feb 13, 2025

Choose a reason for hiding this comment

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

Please see above comment:

These fields:

-application ID
-version code
-uuid (if the customer adds it)

only need to be added to crash and error spans that have stacktraces. This is because these attributes are used to correlate an android stacktrace with the correct mapping file for deobfuscation in the backend.

They do not need to be added to any other spans, as they are only relevant to identifying errors. That is why this class is called the error identifier extractor. Because it extracts the attributes used to identify an error stacktrace

* @param throwable A [Throwable] associated with this event.
*/
fun trackException(throwable: Throwable) {
trackException(throwable, Attributes.empty())

Choose a reason for hiding this comment

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

Wouldn't it be better to pass null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't make a difference

Choose a reason for hiding this comment

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

According to the source code, using Attributes.empty() requires two additional comparisons to achieve the same result.

…irectly accessible, simplified the span processor class init, renamed proguard rules.pro
val WORKFLOW_NAME_KEY: AttributeKey<String> = AttributeKey.stringKey("workflow.name")
val COMPONENT_KEY: AttributeKey<String> = AttributeKey.stringKey("component")

val APPLICATION_ID_KEY: AttributeKey<String> = AttributeKey.stringKey("service.application_id")

Choose a reason for hiding this comment

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

I don't think it's a good idea to have attributes as global properties. It goes against the principle of an independent modular architecture.

Copy link
Contributor

Choose a reason for hiding this comment

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

Some of these are going to be used by multiple modules, so that's why it's helpful to keep them in a common module. I also came across another class we already have where we can park commonly used attributes (I Missed it in my PR as well where I added workflow.name) - AttributeConstants

* @param throwable A [Throwable] associated with this event.
*/
fun trackException(throwable: Throwable) {
trackException(throwable, Attributes.empty())

Choose a reason for hiding this comment

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

According to the source code, using Attributes.empty() requires two additional comparisons to achieve the same result.

@TomasChladekSL TomasChladekSL self-requested a review February 14, 2025 10:01
@@ -0,0 +1,65 @@
package com.splunk.sdk.utils
Copy link
Contributor

@surbhiia surbhiia Feb 14, 2025

Choose a reason for hiding this comment

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

nit: Should we add "common" word in the package name like the other common packages - com.splunk.sdk.common.utils ? If not, we might need to change the package name in pro guard-rules.pro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants