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

Akka HTTP bindFlow instrumentation broken #189

Closed
ryanb93 opened this issue Jan 15, 2021 · 3 comments
Closed

Akka HTTP bindFlow instrumentation broken #189

ryanb93 opened this issue Jan 15, 2021 · 3 comments
Assignees
Labels
bug Something isn't working as designed/intended

Comments

@ryanb93
Copy link

ryanb93 commented Jan 15, 2021

Description

When creating an AkkaHttp server using Http().newServerAt("localhost", 8080).bindFlow(....) instrumentation breaks. This is possibly due to handleWithAsyncHandler not being called, which is where instrumentation is hooked.

Expected Behavior

Transactions are instrumented normally.

Steps to Reproduce

Create a new server as follows:

Http().newServerAt(interface = "localhost", port).bindFlow {
  path("asyncPing") {
    get {
      complete {
        println("request made")
        StatusCodes.OK -> "Hoops!"
      }
    }
  }
}

A test has been created that shows an example of this: main...ryanb93:main

Your Environment

NewRelic Agent: 6.3.0
JVM: Java 11 OpenJDK
Akka Http: 10.2.2
Scala 2.13.3

Additional context

Some additional comments here: #149 (comment)

@ryanb93 ryanb93 added the bug Something isn't working as designed/intended label Jan 15, 2021
@tspring
Copy link
Contributor

tspring commented Jan 15, 2021

@ryanb93 Thanks for this. I'll take a look soon and see if we can't come up with a fix

@ryanb93
Copy link
Author

ryanb93 commented Jan 16, 2021

Thanks

If anyone else is having the same problem, you can keep using the Routing DSL and then bind like this:

    Http()
      .newServerAt(interface, port)
      .connectionSource()
      .to(Sink.foreach(_ handleWithAsyncHandler customRoutes))
      .run()

This starts reporting transactions to the NewRelic agent however all transactions are attributed to Akka/RequestHandler and it can not distinguish between endpoints.

edit:

Additionally using bind instead of bindFlow also works:

Http().newServerAt(interface = "localhost", port).bind {
  path("asyncPing") {
    get {
      complete {
        println("request made")
        StatusCodes.OK -> "Hoops!"
      }
    }
  }
}

@ryanb93
Copy link
Author

ryanb93 commented Jan 18, 2021

Some investigation:

NewRelic hooks into the following methods within akka.http.scaladsl.HttpExt

bindAndHandleAsync
bindAndHandleSync

When a server is created using bindFlow in ServerBuilder the following chain is called:

bindFlow -> bindAndHandleImpl -> bindAndHandle

When a server is created using bind the following chain is called:

bind -> bindAndHandleAsyncImpl -> bindAndHandleAsync -> bindAndHandleImpl -> bindAndHandle
                                                     -> Http2().bindAndHandleAsync //if http2 is enabled

It might be that it's better to hook into the underlying bindAndHandle function as it is called by bindAndHandleAsync, bindAndHandleSync, bind, and bindFlow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working as designed/intended
Projects
Archived in project
Development

No branches or pull requests

4 participants