Guides
Tracing over Kafka
No more MDC.
Tracing requires writing step log id through clients and reading it in servers.
With bitryon-logger library, developers can customize tracing over other protocols.
Configuration YAML file - in spring
In pure java applications, developers need to manually write and read step log id
bitryon:
app-node:
http-header-id-type: 1 # write log/trace id to the http response header; 0 default no write header, 1 trace id, 2 step log id
Write step log id - trace id
Write step log id (trace id) over Kafka:
// Write next step log id (trace id) to metadata/header of the message
import io.bitryon.logger.Logger;
import io.bitryon.logger.PreDefinition;
import io.bitryon.logger.provider.LoggerFactory;
public class ProducerLoggerInterceptor implements ProducerInterceptor<String, String> {
private static final Logger logger = LoggerFactory.getLogger();
@Override
public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
// CRITICAL .getNextStepLogId()
String nextSteplogId = logger.getNextStepLogId();
record.headers().add(PreDefinition.HTTP_HEADER_STEP_LOG_ID, nextSteplogId.getBytes(PreDefinition.CharsetEncoding));
return record;
}
// other code
}
Read step log id - trace id
Read step log id (trace id) over HTTP:
// Read the step log id (trace id) from metadata/header of the message
import io.bitryon.logger.Logger;
import io.bitryon.logger.PreDefinition;
import io.bitryon.logger.provider.LoggerFactory;
public class ConsumerLoggerInterceptor implements ConsumerInterceptor<String, String> {
private static final Logger logger = LoggerFactory.getLogger();
@Override
public ConsumerRecords<String, String> onConsume(ConsumerRecords<String, String> records) {
records.forEach(record -> {
Header header = record.headers().lastHeader(PreDefinition.HTTP_HEADER_STEP_LOG_ID);
if (header!=null) {
String stepLogId = new String(header.value(), PreDefinition.CharsetEncoding);
logger.setStepLogId(stepLogId);
}else {
logger.reset();// reset to restart trace for each consume
}
});
return records;
}
// other code
}
Tracing by reusing HTTP headers
| Type | Key | Default | Description |
|---|---|---|---|
| HTTP_HEADER_STEP_LOG_ID | X-Step-Log-Id | null | Pass the step log id to the next service to track all of the traces. |
| HTTP_HEADER_STEP_TRACE_ID | X-Step-Trace-Id | null | Expose the trace id to HTTP headers |
| HTTP_HEADER_STEP_LOG_SKIP | X-Step-Log-Skip | false | to tell the next service to skip the trace, true skip, null or false not skip |
💡 NoteKafka requires configuring metadata/header Interceptors
Send messages
public class KafkaProducer {
@Resource
MedicService medicService;
private final KafkaTemplate kafkaTemplate;
@Autowired
public KafkaProducer(KafkaTemplate kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void sendMessage(String message) {
medicService.callSelfInvocation(message);
kafkaTemplate.send("demo-topic", message);
}
}
Receive messages
@Service
public class KafkaConsumer {
@Resource
UserService userService;
@KafkaListener(topics = "demo-topic", groupId = "demo-group")
public void listen(String message) {
userService.getBySessionId(message);
}
}
Tracing Logs
2025-11-20 15:42:24.785|http-nio-80-exec-1#38|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|4|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#callSelfInvocation#68#|
[{
"testString": "68ssTfeP43IeSVqFWx1jH1VigFuEdUbt"
}]
2025-11-20 15:42:24.787|http-nio-80-exec-1#38|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|13|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#callSelfInvocation#68#R|
["1763653344787"]
2025-11-20 15:42:26.073|org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1#51|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|14-1|JSON|
UserService.java#io.bitryon.example.web.service.rpc.UserService#getBySessionId#0#|
[{
"sessionId": "68ssTfeP43IeSVqFWx1jH1VigFuEdUbt"
}]
2025-11-20 15:42:26.693|http-nio-80-exec-4#41|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|14-1-2|JSON|
UserServiceImpl.java#io.bitryon.example.web.service.rpc.UserServiceImpl#getBySessionId#45#|
[{
"sessionId": "68ssTfeP43IeSVqFWx1jH1VigFuEdUbt"
}]
2025-11-20 15:42:26.694|http-nio-80-exec-4#41|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|14-1-3|JSON|
UserServiceImpl.java#io.bitryon.example.web.service.rpc.UserServiceImpl#getBySessionId#45#R|
[{
"name": "ra***ly",
"id": 456,
"driverLisenceId": "****************************",
"age": null
}]
2025-11-20 15:42:26.918|org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1#51|7G5HPZyA3QWSF2f1SMRN5qV2U95tjOLi|14-2|JSON|
UserService.java#io.bitryon.example.web.service.rpc.UserService#getBySessionId#0#R|
[{
"name": "ra***ly",
"id": 456,
"driverLisenceId": "****************************",
"age": null
}]