github.com/confluentinc/confluent-kafka-go@v1.9.2/kafka/log.go (about) 1 package kafka 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 /* 9 #include "select_rdkafka.h" 10 */ 11 import "C" 12 13 // LogEvent represent the log from librdkafka internal log queue 14 type LogEvent struct { 15 Name string // Name of client instance 16 Tag string // Log tag that provides context to the log Message (e.g., "METADATA" or "GRPCOORD") 17 Message string // Log message 18 Level int // Log syslog level, lower is more critical. 19 Timestamp time.Time // Log timestamp 20 } 21 22 // newLogEvent creates a new LogEvent from the given rd_kafka_event_t. 23 // 24 // This function does not take ownership of the cEvent pointer. You need to 25 // free its resources using C.rd_kafka_event_destroy afterwards. 26 // 27 // The cEvent object needs to be of type C.RD_KAFKA_EVENT_LOG. Calling this 28 // function with an object of another type has undefined behaviour. 29 func (h *handle) newLogEvent(cEvent *C.rd_kafka_event_t) LogEvent { 30 var tag, message *C.char 31 var level C.int 32 33 C.rd_kafka_event_log(cEvent, &(tag), &(message), &(level)) 34 35 return LogEvent{ 36 Name: h.name, 37 Tag: C.GoString(tag), 38 Message: C.GoString(message), 39 Level: int(level), 40 Timestamp: time.Now(), 41 } 42 } 43 44 // pollLogEvents polls log events from librdkafka and pushes them to toChannel, 45 // until doneChan is closed. 46 // 47 // Each call to librdkafka times out after timeoutMs. If a call to librdkafka 48 // is ongoing when doneChan is closed, the function will wait until the call 49 // returns or times out, whatever happens first. 50 func (h *handle) pollLogEvents(toChannel chan LogEvent, timeoutMs int, doneChan chan bool) { 51 for { 52 select { 53 case <-doneChan: 54 return 55 56 default: 57 cEvent := C.rd_kafka_queue_poll(h.logq, C.int(timeoutMs)) 58 if cEvent == nil { 59 continue 60 } 61 62 if C.rd_kafka_event_type(cEvent) != C.RD_KAFKA_EVENT_LOG { 63 C.rd_kafka_event_destroy(cEvent) 64 continue 65 } 66 67 logEvent := h.newLogEvent(cEvent) 68 C.rd_kafka_event_destroy(cEvent) 69 70 select { 71 case <-doneChan: 72 return 73 74 case toChannel <- logEvent: 75 continue 76 } 77 } 78 } 79 } 80 81 func (logEvent LogEvent) String() string { 82 return fmt.Sprintf( 83 "[%v][%s][%s][%d]%s", 84 logEvent.Timestamp.Format(time.RFC3339), 85 logEvent.Name, 86 logEvent.Tag, 87 logEvent.Level, 88 logEvent.Message) 89 }