public ProducerRecord<K, V> onSend(ProducerRecord<K, V> record) {
        ProducerRecord<K, V> interceptRecord = record;
        for (ProducerInterceptor<K, V> interceptor : this.interceptors) {
            try {
                interceptRecord = interceptor.onSend(interceptRecord);
            } catch (Exception e) {
                // do not propagate interceptor exception, log and continue calling other interceptors
                // be careful not to throw exception from here
                if (record != null)
                    log.warn("Error executing interceptor onSend callback for topic: {}, partition: {}", record.topic(), record.partition(), e);
                else
                    log.warn("Error executing interceptor onSend callback", e);
            }
        }
        return interceptRecord;
    }
This is called when client sends the record to KafkaProducer, before key and value gets serialized.
The method calls {@link ProducerInterceptor#onSend(ProducerRecord)} method. ProducerRecord
returned from the first interceptor's onSend() is passed to the second interceptor onSend(), and so on in the
interceptor chain. The record returned from the last interceptor is returned from this method.

This method does not throw exceptions. Exceptions thrown by any of interceptor methods are caught and ignored.
If an interceptor in the middle of the chain, that normally modifies the record, throws an exception,
the next interceptor in the chain will be called with a record returned by the previous interceptor that did not
throw an exception.

@param record the record from client
@return producer record to send to topic/partition
clients/src/main/java/org/apache/kafka/clients/producer/internals/ProducerInterceptors.java