Created
December 28, 2012 16:17
-
-
Save nt/4399263 to your computer and use it in GitHub Desktop.
Using New Relic with Finagle is a pain
This file contains hidden or 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
import org.apache.thrift.protocol.TProtocolFactory | |
import com.twitter.finagle.{Service, SimpleFilter} | |
import com.twitter.util.{Duration, Time} | |
import org.apache.thrift.transport.TMemoryInputTransport | |
import com.newrelic.api.agent.{Response, Request, NewRelic, Trace} | |
import java.util.Collections | |
class NewRelicFinagleFilter(protocolFactory:TProtocolFactory) extends SimpleFilter[Array[Byte], Array[Byte]] { | |
def apply(request: Array[Byte], service: Service[Array[Byte], Array[Byte]]) = { | |
val start = Time.now | |
val inputTransport = new TMemoryInputTransport(request) | |
val iprot = protocolFactory.getProtocol(inputTransport) | |
val msg = iprot.readMessageBegin() | |
service(request) | |
.onSuccess { _ => | |
val duration = Time.now - start | |
println(msg.name, duration, "ok") | |
reportOk(msg.name, duration) | |
} | |
.onFailure { e => | |
val duration = Time.now - start | |
println(msg.name, duration, e.getClass.getName) | |
reportErr(msg.name, duration, e) | |
} | |
} | |
@Trace(dispatcher = true) | |
def reportOk(uri:String, duration:Duration) { | |
NewRelic.setTransactionName(null, uri) | |
NewRelic.setRequestAndResponse(Req(uri), OK) | |
NewRelic.recordResponseTimeMetric(uri, duration.inMillis) | |
} | |
@Trace(dispatcher = true) | |
def reportErr(uri:String, duration:Duration, e:Throwable) { | |
NewRelic.setTransactionName(null, uri) | |
NewRelic.setRequestAndResponse(Req(uri), Error(e)) | |
NewRelic.noticeError(e) | |
NewRelic.recordResponseTimeMetric(uri, duration.inMillis) | |
} | |
case class Req(uri:String) extends Request { | |
def getRequestURI = uri | |
def getHeader(p1: String) = null | |
def getRemoteUser = null | |
def getParameterNames = Collections.enumeration(Collections.EMPTY_LIST) | |
def getParameterValues(p1: String) = Array[String]() | |
def getAttribute(p1: String) = null | |
} | |
sealed abstract class R extends Response { | |
def setHeader(p1: String, p2: String) {} | |
} | |
object OK extends R { | |
def getStatus = 200 | |
def getStatusMessage = null | |
} | |
case class Error(e:Throwable) extends R { | |
def getStatus = 500 | |
def getStatusMessage = e.getClass.getName | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment