'Pass sleuth BaggageField when span and TraceContext is null
I have very simple scenario. I have a listener, that listens queue:
import brave.Span
import brave.baggage.BaggageField
import brave.propagation.CurrentTraceContext
import brave.propagation.TraceContext
import brave.propagation.TraceContextOrSamplingFlags
import com.fasterxml.jackson.databind.ObjectMapper
import com.bla-bla.aggregatorzoo.api.shared.logging.updateTraceId
import com.bla-bla.content.api.provider.ContentType
import com.bla-bla.content.api.service.ESService
import com.bla-bla.shared.constants.CommonConstants
import org.apache.commons.lang3.StringUtils
import org.apache.logging.log4j.kotlin.Logging
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cloud.aws.messaging.listener.SqsMessageDeletionPolicy
import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener
import org.springframework.cloud.sleuth.BaggageInScope
import org.springframework.cloud.sleuth.Tracer
import org.springframework.messaging.handler.annotation.Headers
import org.springframework.stereotype.Component
@Component
class ESListener(
@Autowired private val esService: ESService,
@Autowired private var traceId: BaggageField,
@Autowired private var ctx: CurrentTraceContext,
@Autowired private var tracer : Tracer
) : Logging {
@Autowired
lateinit var objectMapper: ObjectMapper
@SqsListener(value = ["\${reindex.queue.show}"], deletionPolicy = SqsMessageDeletionPolicy.ALWAYS)
fun reIndexShows(message: String, @Headers headers: Map<String, String>){
processMessage(message, headers, ContentType.SHOW)
}
@SqsListener(value = ["\${reindex.queue.episodes}"], deletionPolicy = SqsMessageDeletionPolicy.ALWAYS)
fun reIndexEpisodes(message: String, @Headers headers: Map<String, String>){
processMessage(message, headers, ContentType.EPISODE)
}
private fun processMessage(message: String, headers: Map<String, String>, type: ContentType) {
try {
val currentSpan = tracer.currentSpan()
val secretBaggageField: BaggageInScope = tracer.getBaggage(CommonConstants.WS_HEADER_TRACED_ID)
val secretBaggage = if (secretBaggageField != null) secretBaggageField.get() else null
logger.info("Super secret baggage item for key [${CommonConstants.WS_HEADER_TRACED_ID}] is [$secretBaggage]" )
if (StringUtils.isNotEmpty(secretBaggage)) {
currentSpan?.event("secret_baggage_received")
currentSpan?.tag("baggage", secretBaggage)
}
val baggageKey = CommonConstants.WS_HEADER_TRACED_ID
val baggageValue = headers[CommonConstants.WS_HEADER_TRACED_ID]
val baggageField: BaggageInScope = tracer.createBaggage(baggageKey)
val context =currentSpan?.context()
baggageField.set(context, baggageValue)
currentSpan?.event("baggage_set")
currentSpan?.tag(baggageKey, baggageValue)
logger.info("Hello from service1. Calling service2")
logger.info("trace-id: ${traceId.value}")
logger.info("got message body: $message")
val traceContext: TraceContext = TraceContext.newBuilder()
.traceId(123456789)
.spanId(123456789)
.build()
val span= tracer.nextSpan(TraceContextOrSamplingFlags.create(traceContext))
.name("dummyContext").start()
// headers[CommonConstants.WS_HEADER_TRACED_ID]?.let {
// traceId.updateTraceId(span?.context())
// traceId.updateValue(it)
//
//// ThreadUtil.updateMDC(
//// hashMapOf(CommonConstants.WS_HEADER_TRACED_ID to it)
//// )
// }
logger.info("trace-id: ${traceId.value}")
logger.info("got message body: $message")
val model=objectMapper.readValue(message, SQSDetail::class.java)
model.payload?.let {
logger.info("Received new SQS message for $type and id: ${it.id}")
esService.doReindex(it.id, type)
}
} catch (e: Exception) {
throw RuntimeException("Cannot process message from SQS", e)
}
}
}
my BaggageFiled configuration:
@Bean
fun traceIdField(): BaggageField? {
return BaggageField.create(CommonConstants.WS_HEADER_TRACED_ID)
}
@Bean
fun mdcScopeDecorator(): CurrentTraceContext.ScopeDecorator? {
return MDCScopeDecorator.newBuilder()
.clear()
.add(
CorrelationScopeConfig.SingleCorrelationField.newBuilder(traceIdField())
.flushOnUpdate()
.build()
)
.build()
}
val currentSpan = tracer.currentSpan()
retruns null in ESListener. No span -> no traceContext -> No BaggageFiled to be propagated. I need to popululate the baggage to pass it else were as a bean.
I tried to create a new Span, start it, set the dummy context to Braver.Tracer and update the value of baggagefield:
headers[CommonConstants.WS_HEADER_TRACED_ID]?.let {
traceId.updateTraceId(span?.context())
traceId.updateValue(it)
}
-it does not work out. Is there any way to do it?
Actually I am able to do it using MDC map:
MDC.setContextMap(
mapOf(
CommonConstants.WS_HEADER_TRACED_ID to headers[CommonConstants.WS_HEADER_TRACED_ID]
))
But I have preference to use sleuth Api to pass over my trace-id as a @Bean.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
