-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #363 from richard-gibson/http4s-blaze
Http4s blaze
- Loading branch information
Showing
66 changed files
with
2,796 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
apply plugin: 'scala' | ||
|
||
dependencies { | ||
implementation(project(":newrelic-api")) | ||
implementation(project(":agent-bridge")) | ||
implementation(project(":newrelic-weaver-api")) | ||
implementation("org.typelevel:cats-effect_2.13:2.5.1") | ||
implementation("org.scala-lang:scala-library:2.13.3") | ||
} | ||
|
||
jar { | ||
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.cats-effect-2', | ||
'Implementation-Title-Alias': 'cats-effect_instrumentation' } | ||
} | ||
|
||
verifyInstrumentation { | ||
passes 'org.typelevel:cats-effect_2.13:[2.1,)' | ||
passes 'org.typelevel:cats-effect_2.12:[2.1,)' | ||
excludeRegex 'org.typelevel:cats-effect_2.1(2|3):3.*' | ||
excludeRegex '.*(RC|M)[0-9]*' | ||
} | ||
|
||
site { | ||
title 'Scala' | ||
type 'Other' | ||
} |
38 changes: 38 additions & 0 deletions
38
instrumentation/cats-effect-2/src/main/java/cats/effect/internals/IOShift.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package cats.effect.internals; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.api.agent.weaver.NewField; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
import static cats.effect.internals.Utils.clearThreadTokenAndRefCountAndTxn; | ||
import static cats.effect.internals.Utils.setThreadTokenAndRefCount; | ||
import static cats.effect.internals.Utils.getThreadTokenAndRefCount; | ||
import static cats.effect.internals.Utils.logTokenInfo; | ||
|
||
@Weave(originalName = "cats.effect.internals.IOShift") | ||
public class IOShift { | ||
|
||
@Weave(originalName = "cats.effect.internals.IOShift$Tick") | ||
public static class Tick { | ||
@NewField | ||
private AgentBridge.TokenAndRefCount tokenAndRefCount; | ||
|
||
public Tick(scala.Function1<scala.util.Either<java.lang.Throwable, scala.runtime.BoxedUnit>, | ||
scala.runtime.BoxedUnit> cb) { | ||
this.tokenAndRefCount = getThreadTokenAndRefCount(); | ||
logTokenInfo(tokenAndRefCount, "IOTick token info set"); | ||
} | ||
|
||
public void run() { | ||
try { | ||
setThreadTokenAndRefCount(this.tokenAndRefCount); | ||
logTokenInfo(tokenAndRefCount, "Token info set in thread"); | ||
Weaver.callOriginal(); | ||
} finally { | ||
logTokenInfo(tokenAndRefCount, "Clearing token info from thread "); | ||
clearThreadTokenAndRefCountAndTxn(this.tokenAndRefCount); | ||
} | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
instrumentation/cats-effect-2/src/main/java/cats/effect/internals/IOTimer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cats.effect.internals; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.api.agent.weaver.NewField; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
import scala.Function1; | ||
import scala.concurrent.ExecutionContext; | ||
import scala.runtime.BoxedUnit; | ||
import scala.util.Either; | ||
|
||
import static cats.effect.internals.Utils.clearThreadTokenAndRefCountAndTxn; | ||
import static cats.effect.internals.Utils.setThreadTokenAndRefCount; | ||
import static cats.effect.internals.Utils.getThreadTokenAndRefCount; | ||
import static cats.effect.internals.Utils.logTokenInfo; | ||
|
||
@Weave(originalName = "cats.effect.internals.IOTimer") | ||
public class IOTimer { | ||
|
||
@Weave(originalName = "cats.effect.internals.IOTimer$ShiftTick") | ||
public static class ShiftTick { | ||
@NewField | ||
private AgentBridge.TokenAndRefCount tokenAndRefCount; | ||
|
||
public ShiftTick(final IOConnection conn, final Function1<Either<Throwable, BoxedUnit>, BoxedUnit> cb, | ||
final ExecutionContext ec) { | ||
this.tokenAndRefCount = getThreadTokenAndRefCount(); | ||
logTokenInfo(tokenAndRefCount, "IOTick token info set"); | ||
} | ||
|
||
public void run() { | ||
try { | ||
setThreadTokenAndRefCount(this.tokenAndRefCount); | ||
logTokenInfo(tokenAndRefCount, "Token info set in thread"); | ||
Weaver.callOriginal(); | ||
} finally { | ||
logTokenInfo(tokenAndRefCount, "Clearing token info from thread "); | ||
clearThreadTokenAndRefCountAndTxn(this.tokenAndRefCount); | ||
} | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
instrumentation/cats-effect-2/src/main/java/cats/effect/internals/Utils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package cats.effect.internals; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
|
||
import java.text.MessageFormat; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.logging.Level; | ||
|
||
public final class Utils { | ||
private Utils() {} | ||
public static AgentBridge.TokenAndRefCount getThreadTokenAndRefCount() { | ||
AgentBridge.TokenAndRefCount tokenAndRefCount = AgentBridge.activeToken.get(); | ||
if (tokenAndRefCount == null) { | ||
Transaction tx = AgentBridge.getAgent().getTransaction(false); | ||
if (tx != null) { | ||
tokenAndRefCount = new AgentBridge.TokenAndRefCount(tx.getToken(), | ||
AgentBridge.getAgent().getTracedMethod(), new AtomicInteger(1)); | ||
} | ||
} else { | ||
tokenAndRefCount.refCount.incrementAndGet(); | ||
} | ||
return tokenAndRefCount; | ||
} | ||
|
||
public static void setThreadTokenAndRefCount(AgentBridge.TokenAndRefCount tokenAndRefCount) { | ||
if (tokenAndRefCount != null) { | ||
AgentBridge.activeToken.set(tokenAndRefCount); | ||
tokenAndRefCount.token.link(); | ||
} | ||
} | ||
|
||
public static void clearThreadTokenAndRefCountAndTxn(AgentBridge.TokenAndRefCount tokenAndRefCount) { | ||
AgentBridge.activeToken.remove(); | ||
if (tokenAndRefCount != null && tokenAndRefCount.refCount.decrementAndGet() == 0) { | ||
tokenAndRefCount.token.expire(); | ||
tokenAndRefCount.token = null; | ||
} | ||
} | ||
|
||
public static void logTokenInfo(AgentBridge.TokenAndRefCount tokenAndRefCount, String msg) { | ||
if (AgentBridge.getAgent().getLogger().isLoggable(Level.FINEST)) { | ||
String tokenMsg = (tokenAndRefCount != null && tokenAndRefCount.token != null) | ||
? String.format("[%s:%s:%d]", tokenAndRefCount.token, tokenAndRefCount.token.getTransaction(), | ||
tokenAndRefCount.refCount.get()) | ||
: "[Empty token]"; | ||
AgentBridge.getAgent().getLogger().log(Level.FINEST, MessageFormat.format("{0}: token info {1}", tokenMsg, msg)); | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
instrumentation/http4s-blaze-client-2.12_0.21/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
apply plugin: 'scala' | ||
|
||
dependencies { | ||
implementation(project(":newrelic-api")) | ||
implementation(project(":agent-bridge")) | ||
implementation(project(":newrelic-weaver-api")) | ||
implementation(project(":newrelic-weaver-scala-api")) | ||
implementation("org.scala-lang:scala-library:2.12.14") | ||
implementation('org.http4s:http4s-blaze-server_2.12:0.21.24') | ||
implementation('org.http4s:http4s-blaze-client_2.12:0.21.24') | ||
testImplementation(project(":instrumentation:cats-effect-2")) { transitive = false } | ||
testImplementation(project(":instrumentation:newrelic-scala-cats-api")) { transitive = false } | ||
testImplementation(project(":newrelic-scala-cats-api")) | ||
testImplementation("org.http4s:http4s-dsl_2.12:0.21.24") | ||
|
||
} | ||
|
||
jar { | ||
manifest { | ||
attributes 'Implementation-Title': 'com.newrelic.instrumentation.http4s-blaze-client-2.12_0.21' | ||
attributes 'Implementation-Vendor': 'New Relic' | ||
attributes 'Implementation-Vendor-Id': 'com.newrelic' | ||
attributes 'Implementation-Version': 1.0 | ||
} | ||
} | ||
verifyInstrumentation { | ||
passes 'org.http4s:http4s-blaze-client_2.12:[0.21,0.22)' | ||
excludeRegex '.*(RC|M)[0-9]*' | ||
} | ||
|
||
sourceSets.main.scala.srcDirs = ['src/main/scala', 'src/main/java'] | ||
sourceSets.main.java.srcDirs = [] |
22 changes: 22 additions & 0 deletions
22
...s-blaze-client-2.12_0.21/src/main/java/org/http4s/BlazeClientBuilder_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.http4s; | ||
|
||
import cats.effect.ConcurrentEffect; | ||
import cats.effect.Resource; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
import com.nr.instrumentation.http4s.NewrelicClientMiddleware$; | ||
import org.http4s.client.Client; | ||
|
||
@Weave(type = MatchType.ExactClass, originalName = "org.http4s.client.blaze.BlazeClientBuilder") | ||
public abstract class BlazeClientBuilder_Instrumentation<F> { | ||
|
||
public ConcurrentEffect F() { | ||
return Weaver.callOriginal(); | ||
} | ||
|
||
public Resource<F, Client<F>> resource() { | ||
Resource<F, Client<F>> delegateResource = Weaver.callOriginal(); | ||
return NewrelicClientMiddleware$.MODULE$.resource(delegateResource, F()); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...lient-2.12_0.21/src/main/scala/com/nr/instrumentation/http4s/InboundResponseWrapper.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.nr.instrumentation.http4s | ||
|
||
import com.newrelic.api.agent.{ExtendedInboundHeaders, HeaderType} | ||
import org.http4s.Response | ||
import org.http4s.util.CaseInsensitiveString | ||
|
||
import collection.JavaConverters._ | ||
import java.util | ||
|
||
class InboundResponseWrapper[F[_]](response: Response[F]) extends ExtendedInboundHeaders { | ||
/** | ||
* Return the type of header key syntax used for this. | ||
* | ||
* @return An <code>enum</code> specifying the type of headers present. | ||
* @since 3.5.0 | ||
*/ | ||
override def getHeaderType: HeaderType = HeaderType.HTTP | ||
|
||
/** | ||
* Returns the value of the specified request header as a <code>String</code>. If the request does not include a | ||
* header with the specified input name, then this method returns <code>null</code>. | ||
* | ||
* @param name The name of the desired request header. | ||
* @return A <code>String</code> containing the value of the specified input request header, or <code>null</code> if the request header is not present. | ||
* @since 3.5.0 | ||
*/ | ||
override def getHeader(name: String): String = | ||
response.headers.find(_.name == CaseInsensitiveString(name)).map(_.value).orNull | ||
|
||
override def getHeaders(name: String): util.List[String] = | ||
response.headers.toList.map(_.name.toString()).asJava | ||
} |
44 changes: 44 additions & 0 deletions
44
...ent-2.12_0.21/src/main/scala/com/nr/instrumentation/http4s/NewrelicClientMiddleware.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.nr.instrumentation.http4s | ||
|
||
import cats.effect.{ConcurrentEffect, Resource, Sync} | ||
import org.http4s.Request | ||
import com.newrelic.agent.bridge.AgentBridge | ||
import com.newrelic.api.agent.HttpParameters | ||
import org.http4s.client.Client | ||
|
||
import java.net.URI | ||
|
||
object NewrelicClientMiddleware { | ||
def construct[F[_] : Sync, T](t: T): F[T] = Sync[F].delay(t) | ||
|
||
def clientResource[F[_] : ConcurrentEffect](client: Client[F]): Client[F] = | ||
Client { req: Request[F] => | ||
for { | ||
seg <- Resource.liftF( | ||
construct { | ||
val txn = AgentBridge.getAgent.getTransaction | ||
val segment = txn.startSegment("HTTP4S client call") | ||
segment.addOutboundRequestHeaders(new OutboundRequestWrapper(req)) | ||
segment | ||
}) | ||
response <- client.run(req) | ||
newRes <- Resource.liftF( | ||
ConcurrentEffect[F].handleErrorWith | ||
(construct { | ||
seg.reportAsExternal(HttpParameters | ||
.library("HTTP4S") | ||
.uri(new URI(req.uri.toString())) | ||
.procedure(req.method.toString()) | ||
.inboundHeaders(new InboundResponseWrapper(response)) | ||
.build()) | ||
seg.end() | ||
response | ||
})(_ => construct(response)) | ||
) | ||
} yield newRes | ||
} | ||
|
||
def resource[F[_] : ConcurrentEffect](delegate: Resource[F, Client[F]]): Resource[F, Client[F]] = | ||
delegate.map(clientResource(_)) | ||
} | ||
|
21 changes: 21 additions & 0 deletions
21
...lient-2.12_0.21/src/main/scala/com/nr/instrumentation/http4s/OutboundRequestWrapper.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.nr.instrumentation.http4s | ||
|
||
import com.newrelic.api.agent.{HeaderType, OutboundHeaders} | ||
import org.http4s.Request | ||
|
||
class OutboundRequestWrapper[F[_]](val request: Request[F]) extends OutboundHeaders { | ||
/** | ||
* Return the type of header key syntax used for this. | ||
* | ||
* @return An <code>enum</code> specifying the type of headers present. | ||
* @since 3.5.0 | ||
*/ | ||
override def getHeaderType: HeaderType = HeaderType.HTTP | ||
|
||
/** | ||
* Sets a response header with the given name and value. | ||
* NO-OP HTTP4s Request Headers are immutable and so can't be set from here | ||
*/ | ||
override def setHeader(name: String, value: String): Unit = { | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
instrumentation/http4s-blaze-client-2.12_0.22/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
apply plugin: 'scala' | ||
|
||
dependencies { | ||
implementation(project(":newrelic-api")) | ||
implementation(project(":agent-bridge")) | ||
implementation(project(":newrelic-weaver-api")) | ||
implementation(project(":newrelic-weaver-scala-api")) | ||
implementation("org.scala-lang:scala-library:2.12.14") | ||
implementation('org.http4s:http4s-blaze-server_2.12:0.22.0') | ||
implementation('org.http4s:http4s-blaze-client_2.12:0.22.0') | ||
testImplementation(project(":instrumentation:cats-effect-2")) { transitive = false } | ||
testImplementation(project(":instrumentation:newrelic-scala-cats-api")) { transitive = false } | ||
testImplementation(project(":newrelic-scala-cats-api")) | ||
testImplementation("org.http4s:http4s-dsl_2.12:0.22.0") | ||
|
||
} | ||
|
||
jar { | ||
manifest { | ||
attributes 'Implementation-Title': 'com.newrelic.instrumentation.http4s-blaze-client-2.12_0.22' | ||
attributes 'Implementation-Vendor': 'New Relic' | ||
attributes 'Implementation-Vendor-Id': 'com.newrelic' | ||
attributes 'Implementation-Version': 1.0 | ||
} | ||
} | ||
verifyInstrumentation { | ||
passes 'org.http4s:http4s-blaze-client_2.12:[0.22.0,1.0)' | ||
excludeRegex '.*(RC|M)[0-9]*' | ||
excludeRegex '.*0.22\\-[0-9].*' | ||
} | ||
|
||
sourceSets.main.scala.srcDirs = ['src/main/scala', 'src/main/java'] | ||
sourceSets.main.java.srcDirs = [] |
Oops, something went wrong.