Feature Idea: Supporting Akka Http clients to monitor external services

Now that general support for Akka Http 10.0.x has been added with 3.44.1, is there any plan on supporting the Akka Http clients so that we can monitor external services too?
I understand this might be related to supporting Akka-Streams, as Akka Http clients like cachedHostConnectionPool are based on akka streams.
Could we open a feature request for this?


New Relic edit

  • I want this, too
  • I have more info to share (reply below)
  • I have a solution for this

0 voters

We take feature ideas seriously and our product managers review every one when plotting their roadmaps. However, there is no guarantee this feature will be implemented. This post ensures the idea is put on the table and discussed though. So please vote and share your extra details with our team.

Thanks for letting us know that this addition would benefit you, @lorenzo.barasti! I have moved your request, and added a poll! :blush: Please vote!

1 Like

I have created an HttpClient that wraps every single http request sent by my application via akka http. I’ve used segments, and this appears to be working reasonably fine. However, the cross application tracing is not working. Am I correct assuming that I need to manually instrumenting my code and create the X-NewRelic-ID and X-NewRelic-Transaction headers to make this happening? Or am I missing something?

Hey there, @bigbird! Unfortunately, we don’t currently have support for Akka Streams. From what I understand, supporting Akka Streams seems like it would effectively solve yours and other fine community members roadblocks:

I will be sure to let our Product Management team know that you are interested in seeing this as well—if you have more to add for their review, please feel free to reply.

Also be sure to vote in these threads and keep the use cases coming!

Thanks again for coming to the community with this—I will leave this thread open so that others can comment with possible successful workarounds. :blush:

We instrument the Akka HTTP client as shown below. Cross-application tracing seems to works fine this way.

First, during initialization we obtain a function for sending requests:

def httpClient: HttpRequest => Future[HttpResponse] = Http().singleRequest(_)

We can now apply instrumentations by wrapping the function:

val instrumentedHttpClient: HttpRequest => Future[HttpResponse] =
  NewRelicInstrumentation.instrumentHttpClient(httpClient)

This is what the instrumentation looks like:

def instrumentHttpClient(httpClient: HttpClient)
                        (implicit ec: ExecutionContext): HttpClient = { request =>
  val segment = NewRelic.getAgent.getTransaction.startSegment("")

  val instrumentedRequest = {
    var outboundHeaders: List[HttpHeader] = Nil
    segment.addOutboundRequestHeaders(new OutboundHeaders {
      override def getHeaderType: HeaderType = HeaderType.HTTP
      override def setHeader(name: String, value: String): Unit = {
        outboundHeaders ::= RawHeader(name, value)
      }
    })
    request.mapHeaders(outboundHeaders ++ _)
  }

  httpClient(instrumentedRequest)
    .andThen {

      case Failure(cause) =>
        NewRelic.noticeError(cause)
        segment.ignore()

      case Success(response) =>
        segment.reportAsExternal(
          HttpParameters
            .library("AkkaHttpClient")
            .uri(URI.create(instrumentedRequest.uri.toString))
            .procedure(instrumentedRequest.method.value)
            .inboundHeaders(new InboundHeaders {
              override def getHeaderType: HeaderType = HeaderType.HTTP
              override def getHeader(name: String): String =
                response.headers.find(_.name == name).map(_.value).orNull
            })
            .build())
        segment.end()
    }
}
3 Likes

Thanks for posting here @nadav.wiener That looks like a great solution to instrument the Akka HTTP client. :smiley:

1 Like