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

Question: How to enable debug logging? #302

Open
MRezaNasirloo opened this issue Apr 12, 2024 · 5 comments
Open

Question: How to enable debug logging? #302

MRezaNasirloo opened this issue Apr 12, 2024 · 5 comments
Labels
needs author feedback Waiting for additional feedback from the author stale

Comments

@MRezaNasirloo
Copy link

How do I enable logging in debug environments?
What I would like to see in the logcat are:

  1. A Metric is being recorded and its attributes
  2. Network calls that the sdk makes
  3. Any errors or warnings that occurs

I tried these properties in gradle.properties with no success

otel.javaagent.debug=true
io.opentelemetry.level=VERBOSE
@aldoKelvianto
Copy link

AFAIK, the current OTel Android SDK doesn't have support for a LogCat Exporter yet (the Java SDK has Exporters to console, but LogCat or Timber is Android-specific).

However, we can write our own Exporter like this:

class LogCatSpanExporter: SpanExporter {
   override fun export(spans: MutableCollection<SpanData>): CompletableResultCode {
       spans.forEach {
           Log.d("logcat-tag", "SpanData: $it")
       }
       return CompletableResultCode.ofSuccess()
   }

   override fun flush(): CompletableResultCode {
       return CompletableResultCode.ofSuccess()
   }

   override fun shutdown(): CompletableResultCode {
       return CompletableResultCode.ofSuccess()
   }
}

And then add it to the OTel RUM:

val otelRumBuilder: OpenTelemetryRumBuilder = OpenTelemetryRum.builder(this, config)
   .addSpanExporterCustomizer {
       OtlpHttpSpanExporter.builder()
           .setEndpoint("http://10.0.2.2:4318/v1/traces")
           .build()
   }
   .addSpanExporterCustomizer {
       LogCatSpanExporter()
   }

val rum: OpenTelemetryRum = otelRumBuilder.build()
example-output-1

example-output-2

Additionally, some events are logged by the SDK, such as frozen frames, slow renders, and network events:

Log.d(RumConstants.OTEL_RUM_LOG_TAG, "* FROZEN RENDER DETECTED: " + duration + " ms. " + count + " times");
Log.d(RumConstants.OTEL_RUM_LOG_TAG, "* Slow render detected: " + duration + " ms. " + count + " times");
Log.d(RumConstants.OTEL_RUM_LOG_TAG, " onAvailable: currentNetwork=" + activeNetwork);

I think it's also possible to use a Processor, like this:

// OtelRumConfig.java
public boolean isLogCatEnabled() {
   return logCatEnabled;
}

// OpenTelemetryRumBuilder.java
if (config.isLogCatEnabled()) {
   // Add processor that prints to LogCat using Log.d or Timber
}

However, this would mean we need to modify the SDK (I'm not too sure about this approach).

@breedx-splk
Copy link
Contributor

Hey @MRezaNasirloo thanks for the question. I think this is probably a duplicate of #142 , which is intended to create the thing that you are asking about. We are looking for contributors who are able to help building this feature.

In the meantime, what @aldoKelvianto suggested is very close to what you can use (thanks for helping out here, @aldoKelvianto !). One thing to point out, is that it looks like the above kinda misuses addSpanExporterCustomizer() -- if you check out the javadocs:

    /**
     * Adds a {@link Function} to invoke with the default {@link SpanExporter} to allow
     * customization. The return value of the {@link Function} will replace the passed-in argument.
     *
     * <p>Multiple calls will execute the customizers in order.
     */

So you have to be careful calling it twice, like the above. Ideally, the LogCatSpanExporter above should take the existing exporter and wrap/delegate to it.

@MRezaNasirloo if you agree that #142 covers this, then let's close this one. Thanks!

@breedx-splk breedx-splk added the needs author feedback Waiting for additional feedback from the author label Apr 15, 2024
@MRezaNasirloo
Copy link
Author

Thank you both.

We are not using Traces and Spans, just Meters: Histogram, Counter, and Gauge. The above solution only works with Spans.

Having a built-in logging mechanism for verifying the correctness of the SDK setup seems crucial. We are unable to verify if metrics are being sent correctly. We saw a few metrics on our backend, but most didn't make it, and there are no errors or warnings that we could use to debug the issue.

Is there a solution that could work with Meters?

@github-actions github-actions bot removed the needs author feedback Waiting for additional feedback from the author label Apr 16, 2024
@breedx-splk
Copy link
Contributor

We are not using Traces and Spans, just Meters: Histogram, Counter, and Gauge. [...]
Is there a solution that could work with Meters?

This is an interesting use case, and one that we have talked about several times in the Android and Client SIGs, with the consensus being that most users would NOT interested in metrics for a few reasons.

Firstly, client instrumentation (including Android) is intended primarily to serve RUM...although admittedly there's a lot more work to be done to even define what RUM is within OpenTelemetry. RUM is interested in user behavior and inter/actions that take place within a user session. Tying metrics to specific user sessions (eg. putting a session ID on data points) would generally explode the cardinality of metric backends. Too many permutations.

Second, we expect that taking measurements in an app and then aggregating them across the landscape of all possible manufacturers, hardware, android versions, networks, countries, VPNs, etc. would provide little actionable value. Maybe you've found otherwise? If so, please help us to better understand this! If we learn from this, we can think about how to add features to the android agent...

All that aside, yes, there is a possible yet more complicated solution.

Instead of calling OpenTelemetryRum.builder(app) you can call OpenTelemetryRum.builder(app, otelSdk). That allows you to preconfigure your own OpenTelemetry SDK instance and pass that in, instead of having the OpenTelemetryRumBuilder create the sdk for you (which is the normal/easier approach).

If you do that, you can configure the SDK to use whatever metric exporters you'd like -- which sounds like you would use a real OTLP exporter to send to a backend AND the metrics logging exporter.

If you truly don't care about tracing or logging, then configuring the SDK won't be too hard. In fact, without tracing or logging, you probably don't benefit from any of the instrumentation in this project, and you can just use the core java sdk to do manual metric instrumentation without this android-agent.

@breedx-splk breedx-splk added the needs author feedback Waiting for additional feedback from the author label Apr 26, 2024
Copy link

This has been automatically marked as stale because it has been marked as needing author feedback and has not had any activity for 21 days. It will be closed automatically if there is no response from the author within 14 additional days from this comment.

@github-actions github-actions bot added the stale label May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs author feedback Waiting for additional feedback from the author stale
Projects
None yet
Development

No branches or pull requests

3 participants