From c74e6ffa680b712f24bbc8bf9b25f67c6668ca25 Mon Sep 17 00:00:00 2001 From: zhangzhibiao Date: Tue, 23 Jun 2026 15:37:59 +0800 Subject: [PATCH] Document custom logger lifetime --- README.md | 13 +++++++++++++ include/pulsar/ClientConfiguration.h | 15 +++++++++++---- include/pulsar/c/client_configuration.h | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0bcae7be..8aff4367 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,19 @@ For the supported Pulsar features, see [Client Feature Matrix](https://pulsar.ap For how to use APIs to publish and consume messages, see [examples](https://github.com/apache/pulsar-client-cpp/tree/main/examples). +## Custom logger lifetime + +The C++ client supports one custom logger factory per process. A logger configured +through `ClientConfiguration::setLogger` or the C API logger functions is shared +by all clients in the same process and is not scoped to an individual client +instance. Set the custom logger before creating clients, and do not expect +different clients to have independent log handlers. + +If an application or language binding exposes logger callbacks, the callback and +its context must remain valid until all Pulsar clients are closed and no +background thread can emit client logs. Avoid tying the callback lifetime to a +single client when multiple clients can exist in the process. + ## Import the library into your project ### CMake with vcpkg integration diff --git a/include/pulsar/ClientConfiguration.h b/include/pulsar/ClientConfiguration.h index b37b7c6a..c21ee5cb 100644 --- a/include/pulsar/ClientConfiguration.h +++ b/include/pulsar/ClientConfiguration.h @@ -187,15 +187,22 @@ class PULSAR_PUBLIC ClientConfiguration { int getMaxBackoffIntervalMs() const; /** - * Configure a custom logger backend to route of Pulsar client library + * Configure a custom logger backend to route Pulsar client library logs * to a different logger implementation. * * By default, log messages are printed on standard output. * * When passed in, the configuration takes ownership of the loggerFactory object. - * The logger factory can only be set once per process. Any subsequent calls to - * set the logger factory will have no effect, though the logger factory object - * will be cleaned up. + * The logger factory is process-wide and is not scoped to a Client instance. + * It can only be set once per process. Any subsequent calls to set the logger + * factory will have no effect, though the logger factory object will be + * cleaned up. + * + * Applications and language bindings that use callback-based logger factories + * should set the logger before creating clients and ensure callback state + * outlives all Pulsar clients and background threads that can emit logs. + * Avoid using per-client callback objects that can be destroyed while another + * client in the same process is still running. */ ClientConfiguration& setLogger(LoggerFactory* loggerFactory); diff --git a/include/pulsar/c/client_configuration.h b/include/pulsar/c/client_configuration.h index 1be7c1f4..8f534383 100644 --- a/include/pulsar/c/client_configuration.h +++ b/include/pulsar/c/client_configuration.h @@ -141,9 +141,25 @@ PULSAR_PUBLIC void pulsar_client_configuration_set_concurrent_lookup_request( PULSAR_PUBLIC int pulsar_client_configuration_get_concurrent_lookup_request( pulsar_client_configuration_t *conf); +/** + * Configure a custom logger for Pulsar client library logs. + * + * The logger is process-wide and is not scoped to a pulsar_client_t instance. + * It can only be set once per process. Applications and language bindings + * should set the logger before creating clients and ensure the logger callback + * context outlives all Pulsar clients and background threads that can emit logs. + */ PULSAR_PUBLIC void pulsar_client_configuration_set_logger(pulsar_client_configuration_t *conf, pulsar_logger logger, void *ctx); +/** + * Configure a custom logger for Pulsar client library logs. + * + * The logger is process-wide and is not scoped to a pulsar_client_t instance. + * It can only be set once per process. Applications and language bindings + * should set the logger before creating clients and ensure the logger callback + * context outlives all Pulsar clients and background threads that can emit logs. + */ PULSAR_PUBLIC void pulsar_client_configuration_set_logger_t(pulsar_client_configuration_t *conf, pulsar_logger_t logger);