Closed rmichela closed 4 years ago
My some developments in this direction. But it wrote in Kotlin. I hope it's could be usefull.
enum class Level {
NONE,
STATUS,
HEADERS,
BODY
}
enum class MethodType {
REQUEST,
REPLAY
}
class GrpcLoggingInterceptor(private val logger: (String) -> Unit = { Log.i("DEFAULT LOGGER", it) }) : ClientInterceptor {
var level = Level.NONE
val logBody
get() = level == Level.BODY
val logHeaders
get() = logBody || level == Level.HEADERS
val logStatus
get() = logBody || level == Level.STATUS
override fun <ReqT : Any, RespT : Any> interceptCall(method: MethodDescriptor<ReqT, RespT>,
callOptions: CallOptions,
next: Channel): ClientCall<ReqT, RespT> {
return object : ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
override fun sendMessage(message: ReqT) {
super.sendMessage(message)
if (logBody) {
logMessage(REQUEST, method, message)
}
}
override fun start(responseListener: Listener<RespT>, headers: Metadata?) {
super.start(object : Listener<RespT>() {
override fun onReady() {
responseListener.onReady()
}
override fun onMessage(message: RespT) {
responseListener.onMessage(message)
if (logBody) {
logMessage(REPLAY, method, message)
}
}
override fun onHeaders(headers: Metadata?) {
responseListener.onHeaders(headers)
if (logHeaders) {
logHeaders(method, headers)
}
}
override fun onClose(status: Status, trailers: Metadata?) {
responseListener.onClose(status, trailers)
if (logStatus) {
logStatus(method, status)
}
}
}, headers)
}
}
}
private fun <ReqT, RespT> logMessage(methodType: MethodType,
method: MethodDescriptor<ReqT, RespT>,
message: Any) = log(
getMethodDirection(methodType)
.plus(getMethodInfo(method))
.plus(message)
)
private fun <ReqT, RespT> logStatus(method: MethodDescriptor<ReqT, RespT>,
status: Status) = log(
getMethodInfo(method)
.plus("\n")
.plus("server status: ${status.code}")
.plus("\n")
.plus("status description: ${status.description}")
.plus("\n")
.plus("cause: ${status.cause}")
)
private fun <ReqT, RespT> logHeaders(method: MethodDescriptor<ReqT, RespT>,
headers: Metadata?) = log(
"HEADERS: "
.plus(getMethodInfo(method))
.plus(headers)
)
private fun <ReqT, RespT> getMethodInfo(method: MethodDescriptor<ReqT, RespT>) = method.fullMethodName.plus(" : [${method.type}] : ")
private fun getMethodDirection(methodType: MethodType) = when (methodType) {
REQUEST -> " --> $methodType "
REPLAY -> " <-- $methodType "
}
private fun log(message: String) {
logger.invoke(message)
}
}
Thanks!
Add client and server interceptors that log/print grpc request debug diagnostics.