@@ -52,6 +52,10 @@ class ConsumeCommand final {
5252 .help (" Stats report interval in milliseconds" )
5353 .scan <' i' , int >()
5454 .default_value (1000 );
55+ command_.add_argument (" --debug" )
56+ .default_value (false )
57+ .implicit_value (true )
58+ .help (" Print each consumed message's metadata" );
5559
5660 parent.add_subparser (command_);
5761 }
@@ -67,6 +71,7 @@ class ConsumeCommand final {
6771 const auto consumer_count = command_.get <int >(" --consumers" );
6872 const auto offset_reset = command_.get (" --offset-reset" );
6973 const auto report_interval_ms = command_.get <int >(" --report-interval-ms" );
74+ const auto debug = command_.get <bool >(" debug" );
7075
7176 if (consumer_count <= 0 ) {
7277 throw std::invalid_argument (
@@ -162,6 +167,14 @@ class ConsumeCommand final {
162167 if (message->err == RD_KAFKA_RESP_ERR_NO_ERROR ) {
163168 consumed_messages++;
164169 consumed_bytes += static_cast <uint64_t >(message->len );
170+ if (debug) {
171+ std::lock_guard<std::mutex> lock (output_mu);
172+ logging::out () << " consumer[" << consumer_index
173+ << " ] message topic=" << message_topic (message)
174+ << " partition=" << message->partition
175+ << " offset=" << message->offset
176+ << " timestamp=" << message_timestamp (message);
177+ }
165178 } else if (message->err != RD_KAFKA_RESP_ERR__PARTITION_EOF ) {
166179 std::lock_guard<std::mutex> lock (output_mu);
167180 logging::err () << " consumer[" << consumer_index
@@ -283,4 +296,41 @@ class ConsumeCommand final {
283296 GUARD (assignment, rd_kafka_topic_partition_list_destroy);
284297 return format_partitions (assignment);
285298 }
299+
300+ static std::string message_topic (const rd_kafka_message_t *message) {
301+ if (message == nullptr || message->rkt == nullptr ) {
302+ return " (unknown)" ;
303+ }
304+ return rd_kafka_topic_name (message->rkt );
305+ }
306+
307+ static std::string message_timestamp (const rd_kafka_message_t *message) {
308+ if (message == nullptr ) {
309+ return " (unknown)" ;
310+ }
311+
312+ rd_kafka_timestamp_type_t timestamp_type = RD_KAFKA_TIMESTAMP_NOT_AVAILABLE ;
313+ const auto timestamp = rd_kafka_message_timestamp (message, ×tamp_type);
314+ if (timestamp < 0 || timestamp_type == RD_KAFKA_TIMESTAMP_NOT_AVAILABLE ) {
315+ return " not available" ;
316+ }
317+
318+ const auto timestamp_time_point = std::chrono::system_clock::time_point (
319+ std::chrono::milliseconds (timestamp));
320+ return logging::format_timestamp (timestamp_time_point) + " (" +
321+ timestamp_type_name (timestamp_type) + " )" ;
322+ }
323+
324+ static std::string
325+ timestamp_type_name (rd_kafka_timestamp_type_t timestamp_type) {
326+ switch (timestamp_type) {
327+ case RD_KAFKA_TIMESTAMP_CREATE_TIME :
328+ return " create_time" ;
329+ case RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME :
330+ return " log_append_time" ;
331+ case RD_KAFKA_TIMESTAMP_NOT_AVAILABLE :
332+ return " not_available" ;
333+ }
334+ return " unknown" ;
335+ }
286336};
0 commit comments