Well basically, have some kind of MDC/NDC functionality of log4j but for vertx "context" (just thinking out loud here not sure this where it would go or even possible).So for instance when you receive an HTTP request you can log- The actual request, maybe the headers- Log some steps of the actual business execution- Log maybe some debug info- Maybe log the query made to a "database"- Log the responseSo this particular request has 5 logs entries that are logged at various levels of the application I.e: inside the web handler, maybe inside the "business" handler, etc...Now lets say you want to associate those 5 log entries to a particular user or tag each log for a specific request with a UUID.With log4j you can push a common value onto the MDC/NDC and all subsequent log entries will be tagged with that value. One you are done with that request you pop the value of the MDC. Unfortunately lo4j MDC/NDC works by thread, since with vertx multiple requests can be received on the same event loop/thread you cannot push/pop values on to the log4j MDC/NDC.
On Wednesday, 7 June 2017 18:46:38 UTC+1, javadevmtl wrote:Well basically, have some kind of MDC/NDC functionality of log4j but for vertx "context" (just thinking out loud here not sure this where it would go or even possible).So for instance when you receive an HTTP request you can log- The actual request, maybe the headers- Log some steps of the actual business execution- Log maybe some debug info- Maybe log the query made to a "database"- Log the responseSo this particular request has 5 logs entries that are logged at various levels of the application I.e: inside the web handler, maybe inside the "business" handler, etc...Now lets say you want to associate those 5 log entries to a particular user or tag each log for a specific request with a UUID.With log4j you can push a common value onto the MDC/NDC and all subsequent log entries will be tagged with that value. One you are done with that request you pop the value of the MDC. Unfortunately lo4j MDC/NDC works by thread, since with vertx multiple requests can be received on the same event loop/thread you cannot push/pop values on to the log4j MDC/NDC.As you point out, the concept of assumes the same thread is exclusive used for the lifetime of the system.
The MDC/NDC construct uses the current thread to store the objects, either in log4j 1.x or slf4j, but log4j2 2.7 has a construct to be able to use something other than the current thread to store the info, that should be possible to use the current context. (https://logging.apache.org/log4j/2.x/manual/thread-context.html)
So I guess no choice we have to pass around that common data through the layers...
I also consider these to be important use cases, and was a little surprised how hard it is to do.
I have had some success using the slf4j MDC (and log4j underneath) for these purposes. Vertx doesn't guarantee you will have exclusive access to threads, but as Tim noted it does have certain guarantees around lambdas.
On Wednesday, 7 June 2017 20:35:15 UTC+1, javadevmtl wrote:So I guess no choice we have to pass around that common data through the layers...Yes, you either have to pass it explicitly or, if it can be passed implicitly if you have lambdas closing over variables in its declaring scope.
I don't think it should be surprising.
MDC, by definition, requires thread affinity. So if you don't have that, it's not going to work. Btw, that's nothing specific to Vert.x, it would be the same in any async system. MDC only works with an "old school" thread per request model, which hopefully is a dying breed.
This isn't a Vert.x guarantee. It's a consequence of the Java language. Any lambda (closure) will capture effectively final variables from it's declaring scope.It's just how Java works and you can do it in any Java program, with or without Vert.x :)
On Thursday, June 8, 2017 at 12:09:53 AM UTC-7, Tim Fox wrote:I don't think it should be surprising.Of course not. You understand vertx too well. :)MDC, by definition, requires thread affinity. So if you don't have that, it's not going to work. Btw, that's nothing specific to Vert.x, it would be the same in any async system. MDC only works with an "old school" thread per request model, which hopefully is a dying breed.I understand MDC uses thread state, but that doesn't mean everything has to be tied to one thread or be synchronous. It just means whoever is managing threads needs to worry about how MDC state gets copied around. If I spin up a worker thread I copy the current MDC to the worker. If I use a thread pool, I set MDC state before the pooled thread starts its task (or better yet, implement it in the thread pool).Vertx knows about all of the threads and facilitates the hand-offs between threads. Since it also knows about slf4j (provides built-in support), what surprised me was that Vertx made no attempt to copy MDC state around when moving between threads. Maybe I am missing something, but I don't see why it couldn't do that to provide better compatibility with existing code and libraries.
Can you give a specific example of what you think Vert.x should do, that it currently doesn't do, using some code? Just so I can understand what you're saying a bit better.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/d0a888ea-8162-4a5d-aef4-ff3886404f29%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi,I have in mind for the near future (3.5?) to provide a facility to achieve this, it is actually related to enable distributed tracing use case.Internally, Vert.x would require changes related to allow this (basically now AsyncResult are constructed, timers and runOnContext).
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/feb601fd-8c67-4dfa-8ba2-2b1efb3cd358%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/1d356f71-12a5-4e55-b5b8-f42e8286844c%40googlegroups.com.
package com.tg.core.extenstions
import io.vertx.ext.web.Route
import io.vertx.ext.web.RoutingContext
import io.vertx.kotlin.coroutines.dispatcher
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.slf4j.MDCContext
import kotlinx.coroutines.experimental.withContext
import org.slf4j.MDC
object Route {
/**
* Like Vert.x's own [io.vertx.ext.web.Route.handler] but can receive
* a coroutine lambda.
*/
fun Route.coroutineHandler(fn: suspend (RoutingContext) -> Unit): Route = handler { ctx ->
MDC.put("request.id", ctx.request().getHeader("REQUEST-ID"))
MDC.put("user.id", ctx.request().getHeader("TG-USER-ID"))
launch(ctx.vertx().dispatcher()) {
withContext(MDCContext()) {
try {
fn(ctx)
} catch (e: Exception) {
ctx.fail(e)
}
}
}
}
}
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/2990f0bd-713a-499d-96aa-d593a417b6ba%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/fbdd6716-fad9-4030-b76a-531bc838b0f0%40googlegroups.com.