elastic / apm-agent-android

Elastic APM Android Agent
Apache License 2.0
20 stars 6 forks source link

Trying to connect elastic agent using kotlin (native android) with flutter using channel and send spans manually #336

Open georgesamirt2 opened 3 months ago

georgesamirt2 commented 3 months ago

I am trying to connect elastic from flutter to native android using kotlin and log API by sending spans as this example

what is the best way to send spans manually from android native code

 private fun sendSpan(endPoint: String, request: String, header: String){
     val tracer = GlobalOpenTelemetry.getTracer(instrumentationScopeName)
     val span = tracer.spanBuilder(endPoint).startSpan()
     span.end()
     GlobalOpenTelemetry.get().logsBridge[endPoint.split("/").last()].let {
         it.logRecordBuilder().let { logRecord->
             logRecord.setBody("REQUEST_HEADER: $header\n\nREQUEST: $request")
             logRecord.emit()
         }
     }
 }
georgesamirt2 commented 3 months ago

@LikeTheSalad

LikeTheSalad commented 3 months ago

Hi @georgesamirt2

Please bear in mind that the agent is meant to be used by native Android apps, however, I guess in theory it could be added to the Android project inside a Flutter project, though it hasn't been tested and we don't guarantee that it will work well in non-android native projects.

Having said that, after making sure that your Android project has the agent properly set up, the way to send telemetry manually is as you've pointed out in your example, i.e:

val tracer = GlobalOpenTelemetry.getTracer(instrumentationScopeName) // Getting a tracer
val span = tracer.spanBuilder("Span name").startSpan() // Starting a span
// Code traced by the span.
span.end() // Ending a span

Bear in mind that spans are first collected and sent in a batch, so you should give it a couple of seconds after calling span.end() before you're able to see the spans in Kibana.

If you want to create a child span inside the first span and see them nested later in Kibana, you should make sure to set the "parent span" context as the current one, like so:

val tracer = GlobalOpenTelemetry.getTracer(instrumentationScopeName)
val parentSpan = tracer.spanBuilder("Parent span name").startSpan()
val parentSpanScope = parentSpan.makeCurrent()
val childSpan = tracer.spanBuilder("Child span name").startSpan()
childSpan.end()
parentSpanScope.close()
parentSpan.end()

For more details you should take a look at the official OTel Java docs on creating spans: https://opentelemetry.io/docs/languages/java/instrumentation/#create-spans

georgesamirt2 commented 3 months ago

I have tried this solution but didn't work as expect. is there a plan to add support to flutter @LikeTheSalad

LikeTheSalad commented 3 months ago

I have tried this solution but didn't work as expect. is there a plan to add support to flutter @LikeTheSalad

Flutter isn't currently on our roadmap, though it's also not impossible for it to become a priority in the future, though as of now, we're focusing on native Android and iOS agents.

When you mentioned that it didn't work as you expected, does it mean that you got some spans in Kibana that didn't have the data you expected? Or does it mean that you didn't get any telemetry in Kibana at all?

georgesamirt2 commented 3 months ago

spans didn't recorded from flutter application to native