-
Notifications
You must be signed in to change notification settings - Fork 75
[fix] Fix issue where custom logger setting is ignored #377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
||
| namespace pulsar { | ||
|
|
||
| static std::atomic<LoggerFactory*> s_defaultLoggerFactory(new ConsoleLoggerFactory()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The s_defaultLoggerFactory is never released. It's not an issue if the application only run once, but if this library is dynamically loaded by an external system, it will be a memory leak.
Could a static logger factory be used instead?
static ConsoleLoggerFactory s_defaultLoggerFactory;Then return &s_defaultLoggerFactory in getLoggerFactory().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BewareMyPower
s_loggerFactory also has the same issue, right? s_loggerFactory used to be a static shared_ptr, but it seems that it was changed to its current type to avoid segfaults during process shutdown.
apache/pulsar#7132
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I fix it like this?
static std::atomic<LoggerFactory*> s_defaultLoggerFactory(nullptr);
LoggerFactory* LogUtils::getLoggerFactory() {
if (s_loggerFactory.load() != nullptr) {
return s_loggerFactory.load();
} else {
if (s_defaultLoggerFactory.load() == nullptr) {
LoggerFactory* oldFactory = nullptr;
LoggerFactory* newFactory = new ConsoleLoggerFactory();
if (!s_defaultLoggerFactory.compare_exchange_strong(oldFactory, newFactory)) {
delete newFactory; // there's already a factory set
}
}
return s_defaultLoggerFactory.load();
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. I think currently it's okay. Your fix here is also good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then this patch LGTM no matter if this fix is applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your confirmation. Then, I will not make the above modifications.
Motivation
I noticed that there are cases where the specified logger factory is not used. For example, if we compile and run the following code, it expects
FileLoggerFactoryto be used, but it actually uses the defaultConsoleLoggerFactory.This happens if logging is performed before
LogUtils::setLoggerFactoryis executed in the constructor ofClientImpl.pulsar-client-cpp/lib/ClientImpl.cc
Lines 94 to 99 in 25ea451
When logging is performed,
LogUtils::getLoggerFactoryis called.pulsar-client-cpp/lib/LogUtils.h
Line 60 in 25ea451
pulsar-client-cpp/lib/LogUtils.h
Line 43 in 25ea451
If the constructor of
ClientImplhas not been executed at this point, the defaultConsoleLoggerFactoryis instantiated, set to the static variables_loggerFactory, and returned to the caller.pulsar-client-cpp/lib/LogUtils.cc
Lines 38 to 44 in 25ea451
Loggers generated from the returned
LoggerFactorywill be set to the static and thread_local variablethreadSpecificLogPtr, and reused from now on.pulsar-client-cpp/lib/LogUtils.h
Lines 38 to 47 in 25ea451
After that,
LogUtils::setLoggerFactoryis executed again in the constructor ofClientImpl, but the value can only be set tos_loggerFactoryonce, and it will be ignored from the second time. This is clearly stated in the comments.pulsar-client-cpp/lib/LogUtils.cc
Lines 30 to 36 in 25ea451
Even if we can set it again, if a logger is already set to
threadSpecificLogPtr, a new logger will not be generated from the newLoggerFactory.Modifications
Keep an instance of the default
ConsoleLoggerFactoryins_defaultLoggerFactory, a variable separate froms_loggerFactory, and return it ifLoggerFactoryis not set yet.In addition, keep the pointer value of the
LoggerFactorythat generated the logger cached inthreadSpecificLogPtr, and regenerate the logger if theLoggerFactorypointer changes.Verifying this change
Documentation
doc-not-needed