Bitryon Logger Docs
GitHub
Guides

Tracing over Kafka

Tracing to the end of life cycle of business logic
Tracing requires writing step log id through producers and reading it in consumers
With bitryon-logger library, developers can customize tracing over any message queue or async channel

Write step log id - trace id

//  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 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

TypeKeyDefaultDescription
HTTP_HEADER_STEP_LOG_IDX-Step-Log-Idnull

Pass the step log id to the next service to track all of the traces.

HTTP_HEADER_STEP_TRACE_IDX-Step-Trace-Idnull

Expose the trace id to HTTP headers

HTTP_HEADER_STEP_LOG_SKIPX-Step-Log-Skipfalse

to tell the next service to skip the trace, true skip, null or false not skip

💡 NoteConfiguring metadata/header Interceptors for Kafka

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
}]