You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2018/05/22 18:59:42 UTC
[incubator-pulsar] branch master updated: Added option for custom
loggers in C++ and C APIs (#1827)
This is an automated email from the ASF dual-hosted git repository.
mmerli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new 26b181e Added option for custom loggers in C++ and C APIs (#1827)
26b181e is described below
commit 26b181e4fcfb9da0827db5f78d29e15c026d20ab
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Tue May 22 11:59:39 2018 -0700
Added option for custom loggers in C++ and C APIs (#1827)
---
pulsar-client-cpp/CMakeLists.txt | 38 +++++---
.../include/pulsar/ClientConfiguration.h | 13 +++
.../{tests/main.cc => include/pulsar/Logger.h} | 41 +++++++--
.../include/pulsar/c/client_configuration.h | 17 +---
pulsar-client-cpp/lib/ClientConfiguration.cc | 7 ++
pulsar-client-cpp/lib/ClientConfigurationImpl.h | 2 +
pulsar-client-cpp/lib/ClientImpl.cc | 21 ++++-
.../{tests/main.cc => lib/Log4CxxLogger.h} | 31 +++++--
pulsar-client-cpp/lib/Log4cxxLogger.cc | 96 ++++++++++++++++++++
pulsar-client-cpp/lib/LogUtils.cc | 55 ++++++-----
pulsar-client-cpp/lib/LogUtils.h | 101 ++++++++++-----------
pulsar-client-cpp/lib/MessageBuilder.cc | 2 +-
pulsar-client-cpp/lib/MessageCrypto.cc | 14 +--
pulsar-client-cpp/lib/SimpleLoggerImpl.cc | 90 ++++++++++++++++++
.../{tests/main.cc => lib/SimpleLoggerImpl.h} | 21 +++--
pulsar-client-cpp/lib/c/c_ClientConfiguration.cc | 30 ++++--
pulsar-client-cpp/perf/CMakeLists.txt | 4 +-
pulsar-client-cpp/perf/PerfConsumer.cc | 2 -
pulsar-client-cpp/perf/PerfProducer.cc | 10 +-
pulsar-client-cpp/tests/main.cc | 1 -
20 files changed, 445 insertions(+), 151 deletions(-)
diff --git a/pulsar-client-cpp/CMakeLists.txt b/pulsar-client-cpp/CMakeLists.txt
index e5fd716..38a4774 100644
--- a/pulsar-client-cpp/CMakeLists.txt
+++ b/pulsar-client-cpp/CMakeLists.txt
@@ -27,6 +27,9 @@ MESSAGE(STATUS "BUILD_TESTS: " ${BUILD_TESTS})
option(LINK_STATIC "Link against static libraries" OFF)
MESSAGE(STATUS "LINK_STATIC: " ${LINK_STATIC})
+option(USE_LOG4CXX "Build with Log4cxx support" OFF)
+MESSAGE(STATUS "USE_LOG4CXX: " ${USE_LOG4CXX})
+
IF (CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo)
ENDIF ()
@@ -65,17 +68,20 @@ if (LINK_STATIC)
find_library(PROTOBUF_LIBRARIES NAMES libprotobuf.a)
find_library(CURL_LIBRARY_PATH NAMES libcurl.a curl)
find_library(LIB_JSON NAMES libjsoncpp.a libjsoncpp_static.a)
- find_library(LOG4CXX_LIBRARY_PATH NAMES liblog4cxx.a)
-
- # Libraries needed by log4cxx to link statically with
- find_library(APR_LIBRARY_PATH NAMES libapr-1.a PATHS /usr/lib /usr/local/apr/lib /usr/local/opt/apr/libexec/lib/)
- find_library(APR_UTIL_LIBRARY_PATH NAMES libaprutil-1.a PATHS /usr/lib /usr/local/apr/lib /usr/local/opt/apr-util/libexec/lib/)
- find_library(EXPAT_LIBRARY_PATH NAMES libexpat.a expat)
- if (APPLE)
- find_library(ICONV_LIBRARY_PATH NAMES libiconv.a iconv)
- else ()
- set(ICONV_LIBRARY_PATH )
- endif ()
+
+ if (USE_LOG4CXX)
+ find_library(LOG4CXX_LIBRARY_PATH NAMES liblog4cxx.a)
+
+ # Libraries needed by log4cxx to link statically with
+ find_library(APR_LIBRARY_PATH NAMES libapr-1.a PATHS /usr/lib /usr/local/apr/lib /usr/local/opt/apr/libexec/lib/)
+ find_library(APR_UTIL_LIBRARY_PATH NAMES libaprutil-1.a PATHS /usr/lib /usr/local/apr/lib /usr/local/opt/apr-util/libexec/lib/)
+ find_library(EXPAT_LIBRARY_PATH NAMES libexpat.a expat)
+ if (APPLE)
+ find_library(ICONV_LIBRARY_PATH NAMES libiconv.a iconv)
+ else ()
+ set(ICONV_LIBRARY_PATH )
+ endif (APPLE)
+ endif (USE_LOG4CXX)
else()
# Link to shared libraries
find_package(ZLIB REQUIRED)
@@ -90,7 +96,9 @@ else()
find_library(LIB_JSON jsoncpp)
find_library(LOG4CXX_LIBRARY_PATH log4cxx)
find_library(CURL_LIBRARY_PATH curl)
- find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h)
+ if (USE_LOG4CXX)
+ find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h)
+ endif (USE_LOG4CXX)
endif (LINK_STATIC)
@@ -140,7 +148,11 @@ if (BUILD_TESTS)
endif ()
find_path(JSON_INCLUDE_PATH jsoncpp)
-find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h)
+
+if (USE_LOG4CXX)
+ set(CMAKE_CXX_FLAGS " -DUSE_LOG4CXX ${CMAKE_CXX_FLAGS}")
+ find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h)
+endif (USE_LOG4CXX)
if (NOT LIB_JSON)
find_library(LIB_JSON json_cpp)
diff --git a/pulsar-client-cpp/include/pulsar/ClientConfiguration.h b/pulsar-client-cpp/include/pulsar/ClientConfiguration.h
index 137d528..eedf716 100644
--- a/pulsar-client-cpp/include/pulsar/ClientConfiguration.h
+++ b/pulsar-client-cpp/include/pulsar/ClientConfiguration.h
@@ -20,6 +20,8 @@
#define PULSAR_CLIENTCONFIGURATION_H_
#include <pulsar/Authentication.h>
+#include <pulsar/Logger.h>
+
#pragma GCC visibility push(default)
namespace pulsar {
class PulsarWrapper;
@@ -105,6 +107,7 @@ class ClientConfiguration {
* Initialize the log configuration
*
* @param logConfFilePath path of the configuration file
+ * @deprecated
*/
ClientConfiguration& setLogConfFilePath(const std::string& logConfFilePath);
@@ -113,6 +116,16 @@ class ClientConfiguration {
*/
const std::string& getLogConfFilePath() const;
+ /**
+ * Configure a custom logger backend to route of Pulsar client library
+ * to a different logger implementation.
+ *
+ * By default, log messages are printed on standard output.
+ */
+ ClientConfiguration& setLogger(LoggerFactoryPtr loggerFactory);
+
+ LoggerFactoryPtr getLogger() const;
+
ClientConfiguration& setUseTls(bool useTls);
bool isUseTls() const;
diff --git a/pulsar-client-cpp/tests/main.cc b/pulsar-client-cpp/include/pulsar/Logger.h
similarity index 57%
copy from pulsar-client-cpp/tests/main.cc
copy to pulsar-client-cpp/include/pulsar/Logger.h
index a600af3..e319a04 100644
--- a/pulsar-client-cpp/tests/main.cc
+++ b/pulsar-client-cpp/include/pulsar/Logger.h
@@ -16,11 +16,36 @@
* specific language governing permissions and limitations
* under the License.
*/
-#include <LogUtils.h>
-#include <gmock/gmock.h>
-
-int main(int argc, char **argv) {
- LogUtils::init("log4cxx.conf");
- ::testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
-}
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#pragma GCC visibility push(default)
+
+namespace pulsar {
+
+class Logger {
+ public:
+ enum Level
+ {
+ DEBUG = 0,
+ INFO = 1,
+ WARN = 2,
+ ERROR = 3
+ };
+
+ virtual bool isEnabled(Level level) = 0;
+
+ virtual void log(Level level, int line, const std::string& message) = 0;
+};
+
+class LoggerFactory {
+ public:
+ virtual ~LoggerFactory() {}
+
+ virtual Logger* getLogger(const std::string& fileName) = 0;
+};
+
+typedef boost::shared_ptr<LoggerFactory> LoggerFactoryPtr;
+} // namespace pulsar
+#pragma GCC visibility pop
diff --git a/pulsar-client-cpp/include/pulsar/c/client_configuration.h b/pulsar-client-cpp/include/pulsar/c/client_configuration.h
index 7725e7c..b04c21d 100644
--- a/pulsar-client-cpp/include/pulsar/c/client_configuration.h
+++ b/pulsar-client-cpp/include/pulsar/c/client_configuration.h
@@ -25,6 +25,10 @@ extern "C" {
#pragma GCC visibility push(default)
+typedef enum { pulsar_DEBUG = 0, pulsar_INFO = 1, pulsar_WARN = 2, pulsar_ERROR = 3 } pulsar_logger_level_t;
+
+typedef void (*pulsar_logger)(pulsar_logger_level_t level, const char *file, int line, const char *message);
+
typedef struct _pulsar_client_configuration pulsar_client_configuration_t;
typedef struct _pulsar_authentication pulsar_authentication_t;
@@ -101,18 +105,7 @@ void pulsar_client_configuration_set_concurrent_lookup_request(pulsar_client_con
*/
int pulsar_client_configuration_get_concurrent_lookup_request(pulsar_client_configuration_t *conf);
-/**
- * Initialize the log configuration
- *
- * @param logConfFilePath path of the configuration file
- */
-void pulsar_client_configuration_set_log_conf_file_path(pulsar_client_configuration_t *conf,
- const char *logConfFilePath);
-
-/**
- * Get the path of log configuration file (log4cpp)
- */
-const char *pulsar_client_configuration_get_log_conf_file_path(pulsar_client_configuration_t *conf);
+void pulsar_client_configuration_logger(pulsar_client_configuration_t *conf, pulsar_logger logger);
void pulsar_client_configuration_set_use_tls(pulsar_client_configuration_t *conf, int useTls);
diff --git a/pulsar-client-cpp/lib/ClientConfiguration.cc b/pulsar-client-cpp/lib/ClientConfiguration.cc
index 6f011e3..246c7af 100644
--- a/pulsar-client-cpp/lib/ClientConfiguration.cc
+++ b/pulsar-client-cpp/lib/ClientConfiguration.cc
@@ -96,6 +96,13 @@ ClientConfiguration& ClientConfiguration::setLogConfFilePath(const std::string&
const std::string& ClientConfiguration::getLogConfFilePath() const { return impl_->logConfFilePath; }
+ClientConfiguration& ClientConfiguration::setLogger(LoggerFactoryPtr loggerFactory) {
+ impl_->loggerFactory = loggerFactory;
+ return *this;
+}
+
+LoggerFactoryPtr ClientConfiguration::getLogger() const { return impl_->loggerFactory; }
+
ClientConfiguration& ClientConfiguration::setStatsIntervalInSeconds(
const unsigned int& statsIntervalInSeconds) {
impl_->statsIntervalInSeconds = statsIntervalInSeconds;
diff --git a/pulsar-client-cpp/lib/ClientConfigurationImpl.h b/pulsar-client-cpp/lib/ClientConfigurationImpl.h
index 4ea77cf..b5da790 100644
--- a/pulsar-client-cpp/lib/ClientConfigurationImpl.h
+++ b/pulsar-client-cpp/lib/ClientConfigurationImpl.h
@@ -34,6 +34,8 @@ struct ClientConfigurationImpl {
std::string tlsTrustCertsFilePath;
bool tlsAllowInsecureConnection;
unsigned int statsIntervalInSeconds;
+ LoggerFactoryPtr loggerFactory;
+
ClientConfigurationImpl()
: authenticationPtr(AuthFactory::Disabled()),
ioThreads(1),
diff --git a/pulsar-client-cpp/lib/ClientImpl.cc b/pulsar-client-cpp/lib/ClientImpl.cc
index 1390336..80f947b 100644
--- a/pulsar-client-cpp/lib/ClientImpl.cc
+++ b/pulsar-client-cpp/lib/ClientImpl.cc
@@ -24,6 +24,8 @@
#include "ReaderImpl.h"
#include "PartitionedProducerImpl.h"
#include "PartitionedConsumerImpl.h"
+#include "SimpleLoggerImpl.h"
+#include "Log4CxxLogger.h"
#include <boost/bind.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <sstream>
@@ -73,7 +75,24 @@ ClientImpl::ClientImpl(const std::string& serviceUrl, const ClientConfiguration&
producerIdGenerator_(0),
consumerIdGenerator_(0),
requestIdGenerator_(0) {
- LogUtils::init(clientConfiguration.getLogConfFilePath());
+ if (clientConfiguration.getLogger()) {
+ // A logger factory was explicitely configured. Let's just use that
+ LogUtils::setLoggerFactory(clientConfiguration.getLogger());
+ } else {
+#ifdef USE_LOG4CXX
+ if (!clientConfiguration.getLogConfFilePath().empty()) {
+ // A log4cxx log file was passed through deprecated parameter. Use that to configure Log4CXX
+ LogUtils::setLoggerFactory(Log4CxxLogger::create(clientConfiguration.getLogConfFilePath()));
+ } else {
+ // Use default simple console logger
+ LogUtils::setLoggerFactory(SimpleLoggerFactory::create());
+ }
+#else
+ // Use default simple console logger
+ LogUtils::setLoggerFactory(SimpleLoggerFactory::create());
+#endif
+ }
+
if (serviceUrl_.compare(0, 4, "http") == 0) {
LOG_DEBUG("Using HTTP Lookup");
lookupServicePtr_ =
diff --git a/pulsar-client-cpp/tests/main.cc b/pulsar-client-cpp/lib/Log4CxxLogger.h
similarity index 66%
copy from pulsar-client-cpp/tests/main.cc
copy to pulsar-client-cpp/lib/Log4CxxLogger.h
index a600af3..184c336 100644
--- a/pulsar-client-cpp/tests/main.cc
+++ b/pulsar-client-cpp/lib/Log4CxxLogger.h
@@ -16,11 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
-#include <LogUtils.h>
-#include <gmock/gmock.h>
-
-int main(int argc, char **argv) {
- LogUtils::init("log4cxx.conf");
- ::testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
-}
+
+#pragma once
+
+#include <pulsar/Logger.h>
+
+#ifdef USE_LOG4CXX
+
+#pragma GCC visibility push(default)
+
+namespace pulsar {
+
+class Log4CxxLoggerFactory : public LoggerFactory {
+ public:
+ static LoggerFactoryPtr create();
+ static LoggerFactoryPtr create(const std::string& log4cxxConfFile);
+
+ Logger* getLogger(const std::string& fileName);
+};
+} // namespace pulsar
+
+#pragma GCC visibility pop
+
+#endif
diff --git a/pulsar-client-cpp/lib/Log4cxxLogger.cc b/pulsar-client-cpp/lib/Log4cxxLogger.cc
new file mode 100644
index 0000000..99cc614
--- /dev/null
+++ b/pulsar-client-cpp/lib/Log4cxxLogger.cc
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Log4CxxLogger.h"
+#include <iostream>
+
+#ifdef USE_LOG4CXX
+
+#include <log4cxx/logger.h>
+#include <log4cxx/logmanager.h>
+#include <log4cxx/consoleappender.h>
+#include <log4cxx/propertyconfigurator.h>
+#include <log4cxx/patternlayout.h>
+
+using namespace log4cxx;
+
+namespace pulsar {
+
+class Log4CxxLogger : public Logger {
+ std::string _fileName;
+ LoggerPtr _logger;
+
+ public:
+ Log4CxxLogger(const std::string &fileName)
+ : _fileName(fileName), _logger(log4cxx::Logger::getLogger(LOG_CATEGORY_NAME + fileName)) {}
+
+ bool isEnabled(Level level) { return _logger->isEnabledFor(getLevel(level)); }
+
+ void log(Level level, int line, const std::string &message) {
+ spi::LocationInfo location(_fileName.c_str(), "", line);
+ _logger->forcedLogLS(getLevel(level), message, location);
+ }
+
+ private:
+ static log4cxx::LevelPtr getLevel(Level level) {
+ switch (level) {
+ case DEBUG:
+ return log4cxx::Level::getDebug();
+ case INFO:
+ return log4cxx::Level::getInfo();
+ case WARN:
+ return log4cxx::Level::getWarn();
+ case ERROR:
+ return log4cxx::Level::getError();
+ }
+ }
+};
+
+LoggerFactoryPtr Log4CxxLoggerFactory::create() {
+ if (!LogManager::getLoggerRepository()->isConfigured()) {
+ LogManager::getLoggerRepository()->setConfigured(true);
+ LoggerPtr root = log4cxx::Logger::getRootLogger();
+ static const LogString TTCC_CONVERSION_PATTERN(LOG4CXX_STR("%d{HH:mm:ss.SSS} [%t] %-5p %l - %m%n"));
+ LayoutPtr layout(new PatternLayout(TTCC_CONVERSION_PATTERN));
+ AppenderPtr appender(new ConsoleAppender(layout));
+ root->setLevel(log4cxx::Level::getInfo());
+ root->addAppender(appender);
+ }
+
+ return LoggerFactoryPtr(new Log4CxxLoggerFactory());
+}
+
+LoggerFactoryPtr Log4CxxLoggerFactory::create(const std::string &log4cxxConfFile) {
+ try {
+ log4cxx::PropertyConfigurator::configure(log4cxxConfFile);
+ } catch (const std::exception &e) {
+ std::cerr << "exception caught while configuring log4cpp via '" << log4cxxConfFile
+ << "': " << e.what() << std::endl;
+ } catch (...) {
+ std::cerr << "unknown exception while configuring log4cpp via '" << log4cxxConfFile << "'."
+ << std::endl;
+ }
+
+ return LoggerFactoryPtr(new Log4CxxLoggerFactory());
+}
+
+Logger *Log4CxxLoggerFactory::getLogger(const std::string &fileName) { return new Log4CxxLogger(fileName); }
+} // namespace pulsar
+
+#endif // USE_LOG4CXX
diff --git a/pulsar-client-cpp/lib/LogUtils.cc b/pulsar-client-cpp/lib/LogUtils.cc
index 70507d9..2192327 100644
--- a/pulsar-client-cpp/lib/LogUtils.cc
+++ b/pulsar-client-cpp/lib/LogUtils.cc
@@ -18,35 +18,34 @@
*/
#include "LogUtils.h"
-#include <log4cxx/logger.h>
-#include <log4cxx/logmanager.h>
-#include <log4cxx/consoleappender.h>
-#include <log4cxx/propertyconfigurator.h>
-#include <log4cxx/patternlayout.h>
#include <iostream>
-using namespace log4cxx;
-
-void LogUtils::init(const std::string& logfilePath) {
- try {
- if (logfilePath.empty()) {
- if (!LogManager::getLoggerRepository()->isConfigured()) {
- LogManager::getLoggerRepository()->setConfigured(true);
- LoggerPtr root = Logger::getRootLogger();
- static const LogString TTCC_CONVERSION_PATTERN(
- LOG4CXX_STR("%d{HH:mm:ss.SSS} [%t] %-5p %l - %m%n"));
- LayoutPtr layout(new PatternLayout(TTCC_CONVERSION_PATTERN));
- AppenderPtr appender(new ConsoleAppender(layout));
- root->setLevel(log4cxx::Level::getInfo());
- root->addAppender(appender);
- }
- } else {
- log4cxx::PropertyConfigurator::configure(logfilePath);
- }
- } catch (const std::exception& e) {
- std::cerr << "exception caught while configuring log4cpp via '" << logfilePath << "': " << e.what()
- << std::endl;
- } catch (...) {
- std::cerr << "unknown exception while configuring log4cpp via '" << logfilePath << "'." << std::endl;
+#include "SimpleLoggerImpl.h"
+#include "Log4CxxLogger.h"
+
+namespace pulsar {
+
+void LogUtils::init(const std::string &logfilePath) {
+// If this is called explicitely, we fallback to Log4cxx config, if enabled
+
+#ifdef USE_LOG4CXX
+ if (!logfilePath.empty()) {
+ setLoggerFactory(Log4CxxLoggerFactory::create(logfilePath));
+ } else {
+ setLoggerFactory(Log4CxxLoggerFactory::create());
}
+#endif // USE_LOG4CXX
}
+
+static LoggerFactoryPtr s_loggerFactory;
+
+void LogUtils::setLoggerFactory(LoggerFactoryPtr loggerFactory) { s_loggerFactory = loggerFactory; }
+
+LoggerFactoryPtr LogUtils::getLoggerFactory() {
+ if (!s_loggerFactory) {
+ s_loggerFactory.reset(new SimpleLoggerFactory());
+ }
+ return s_loggerFactory;
+}
+
+} // namespace pulsar
\ No newline at end of file
diff --git a/pulsar-client-cpp/lib/LogUtils.h b/pulsar-client-cpp/lib/LogUtils.h
index 6371efe..12a5b06 100644
--- a/pulsar-client-cpp/lib/LogUtils.h
+++ b/pulsar-client-cpp/lib/LogUtils.h
@@ -16,68 +16,64 @@
* specific language governing permissions and limitations
* under the License.
*/
-#ifndef LOG_UTIL_H
-#define LOG_UTIL_H
+
+#pragma once
#include <boost/thread/tss.hpp>
-#include <log4cxx/logger.h>
#include <string>
+#include <sstream>
-#define DECLARE_LOG_OBJECT() \
- static log4cxx::LoggerPtr& logger() { \
- static boost::thread_specific_ptr<log4cxx::LoggerPtr> threadSpecificLogPtr; \
- log4cxx::LoggerPtr* ptr = threadSpecificLogPtr.get(); \
- if (!ptr) { \
- threadSpecificLogPtr.reset( \
- new log4cxx::LoggerPtr(log4cxx::Logger::getLogger(LOG_CATEGORY_NAME __FILE__))); \
- ptr = threadSpecificLogPtr.get(); \
- } \
- return *ptr; \
- }
+#include <pulsar/Logger.h>
+
+namespace pulsar {
+
+#define PULSAR_UNLIKELY(expr) __builtin_expect(expr, 0)
-#define LOG_DEBUG(message) \
- { \
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) { \
- ::log4cxx::helpers::MessageBuffer oss_; \
- logger()->forcedLog(::log4cxx::Level::getDebug(), oss_.str(((std::ostream&)oss_) << message), \
- LOG4CXX_LOCATION); \
- } \
+#define DECLARE_LOG_OBJECT() \
+ static pulsar::Logger* logger() { \
+ static boost::thread_specific_ptr<pulsar::Logger> threadSpecificLogPtr; \
+ pulsar::Logger* ptr = threadSpecificLogPtr.get(); \
+ if (PULSAR_UNLIKELY(!ptr)) { \
+ threadSpecificLogPtr.reset(pulsar::LogUtils::getLoggerFactory()->getLogger(__FILE__)); \
+ ptr = threadSpecificLogPtr.get(); \
+ } \
+ return ptr; \
}
-#define LOG_INFO(message) \
- { \
- if (logger()->isInfoEnabled()) { \
- ::log4cxx::helpers::MessageBuffer oss_; \
- logger()->forcedLog(::log4cxx::Level::getInfo(), oss_.str(((std::ostream&)oss_) << message), \
- LOG4CXX_LOCATION); \
- } \
+#define LOG_DEBUG(message) \
+ { \
+ if (PULSAR_UNLIKELY(logger()->isEnabled(pulsar::Logger::DEBUG))) { \
+ std::stringstream ss; \
+ ss << message; \
+ logger()->log(pulsar::Logger::DEBUG, __LINE__, ss.str()); \
+ } \
}
-#define LOG_WARN(message) \
- { \
- if (logger()->isWarnEnabled()) { \
- ::log4cxx::helpers::MessageBuffer oss_; \
- logger()->forcedLog(::log4cxx::Level::getWarn(), oss_.str(((std::ostream&)oss_) << message), \
- LOG4CXX_LOCATION); \
- } \
+#define LOG_INFO(message) \
+ { \
+ if (logger()->isEnabled(pulsar::Logger::INFO)) { \
+ std::stringstream ss; \
+ ss << message; \
+ logger()->log(pulsar::Logger::INFO, __LINE__, ss.str()); \
+ } \
}
-#define LOG_ERROR(message) \
- { \
- if (logger()->isErrorEnabled()) { \
- ::log4cxx::helpers::MessageBuffer oss_; \
- logger()->forcedLog(::log4cxx::Level::getError(), oss_.str(((std::ostream&)oss_) << message), \
- LOG4CXX_LOCATION); \
- } \
+#define LOG_WARN(message) \
+ { \
+ if (logger()->isEnabled(pulsar::Logger::WARN)) { \
+ std::stringstream ss; \
+ ss << message; \
+ logger()->log(pulsar::Logger::WARN, __LINE__, ss.str()); \
+ } \
}
-#define LOG_FATAL(message) \
- { \
- if (logger()->isFatalEnabled()) { \
- ::log4cxx::helpers::MessageBuffer oss_; \
- logger()->forcedLog(::log4cxx::Level::getFatal(), oss_.str(((std::ostream&)oss_) << message), \
- LOG4CXX_LOCATION); \
- } \
+#define LOG_ERROR(message) \
+ { \
+ if (logger()->isEnabled(pulsar::Logger::ERROR)) { \
+ std::stringstream ss; \
+ ss << message; \
+ logger()->log(pulsar::Logger::ERROR, __LINE__, ss.str()); \
+ } \
}
#pragma GCC visibility push(default)
@@ -85,8 +81,11 @@
class LogUtils {
public:
static void init(const std::string& logConfFilePath);
+
+ static void setLoggerFactory(LoggerFactoryPtr loggerFactory);
+
+ static LoggerFactoryPtr getLoggerFactory();
};
#pragma GCC visibility pop
-
-#endif
+}
diff --git a/pulsar-client-cpp/lib/MessageBuilder.cc b/pulsar-client-cpp/lib/MessageBuilder.cc
index 4ea21b2..5dd9df1 100644
--- a/pulsar-client-cpp/lib/MessageBuilder.cc
+++ b/pulsar-client-cpp/lib/MessageBuilder.cc
@@ -48,7 +48,7 @@ Message MessageBuilder::build() { return Message(impl_); }
void MessageBuilder::checkMetadata() {
if (!impl_.get()) {
- LOG_FATAL("Cannot reuse the same message builder to build a message");
+ LOG_ERROR("Cannot reuse the same message builder to build a message");
abort();
}
}
diff --git a/pulsar-client-cpp/lib/MessageCrypto.cc b/pulsar-client-cpp/lib/MessageCrypto.cc
index c5f41d8..0203660 100644
--- a/pulsar-client-cpp/lib/MessageCrypto.cc
+++ b/pulsar-client-cpp/lib/MessageCrypto.cc
@@ -147,7 +147,7 @@ Result MessageCrypto::addPublicKeyCipher(std::set<std::string>& keyNames,
// Generate data key
RAND_bytes(dataKey_.get(), dataKeyLen_);
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string dataKeyStr(reinterpret_cast<char*>(dataKey_.get()), dataKeyLen_);
std::string strHex = stringToHex(dataKeyStr, dataKeyStr.size());
LOG_DEBUG(logCtx_ << "Generated Data key " << strHex);
@@ -203,7 +203,7 @@ Result MessageCrypto::addPublicKeyCipher(const std::string& keyName, const Crypt
// Add a new entry or replace existing entry, if one is present.
encryptedDataKeyMap_[keyName] = eki;
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strHex = stringToHex(encryptedKeyStr, encryptedKeyStr.size());
LOG_DEBUG(logCtx_ << " Data key encrypted for key " << keyName
<< ". Encrypted key size = " << encryptedKeyStr.size() << ", value = " << strHex);
@@ -253,7 +253,7 @@ bool MessageCrypto::encrypt(std::set<std::string>& encKeys, const CryptoKeyReade
proto::EncryptionKeys* encKeys = proto::EncryptionKeys().New();
encKeys->set_key(keyName);
encKeys->set_value(keyInfo->getKey());
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strHex = stringToHex(keyInfo->getKey(), keyInfo->getKey().size());
LOG_DEBUG(logCtx_ << " Encrypted data key added for key " << keyName << ". Encrypted key size = "
<< keyInfo->getKey().size() << ", value = " << strHex);
@@ -323,7 +323,7 @@ bool MessageCrypto::encrypt(std::set<std::string>& encKeys, const CryptoKeyReade
return false;
}
encryptedPayload.bytesWritten(tagLen_);
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strPayloadHex = stringToHex(payload.data(), payload.readableBytes());
std::string strHex = stringToHex(encryptedPayload.data(), encryptedPayload.readableBytes());
LOG_DEBUG(logCtx_ << " Original size = " << payload.readableBytes() << ", value = " << strPayloadHex
@@ -376,7 +376,7 @@ bool MessageCrypto::decryptDataKey(const std::string& keyName, const std::string
std::string keyDigestStr(reinterpret_cast<char*>(keyDigest), digestLen);
std::string dataKeyStr(reinterpret_cast<char*>(dataKey_.get()), dataKeyLen_);
dataKeyCache_[keyDigestStr] = make_pair(dataKeyStr, boost::posix_time::second_clock::universal_time());
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strHex = stringToHex(dataKeyStr, dataKeyStr.size());
LOG_DEBUG(logCtx_ << "Data key for key " << keyName << " decrypted. Decrypted data key is "
<< strHex);
@@ -395,7 +395,7 @@ bool MessageCrypto::decryptData(const std::string& dataKeySecret, const proto::M
EVP_CIPHER_CTX* cipherCtx = NULL;
decryptedPayload = SharedBuffer::allocate(payload.readableBytes() + EVP_MAX_BLOCK_LENGTH + tagLen_);
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strHex = stringToHex(payload.data(), payload.readableBytes());
LOG_DEBUG(logCtx_ << "Attempting to decrypt data with encrypted size " << payload.readableBytes()
<< ", data = " << strHex);
@@ -443,7 +443,7 @@ bool MessageCrypto::decryptData(const std::string& dataKeySecret, const proto::M
return false;
}
decryptedPayload.bytesWritten(decLen);
- if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {
+ if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::DEBUG))) {
std::string strHex = stringToHex(decryptedPayload.data(), decryptedPayload.readableBytes());
LOG_DEBUG(logCtx_ << "Data decrypted. Decrypted size = " << decryptedPayload.readableBytes()
<< ", data = " << strHex);
diff --git a/pulsar-client-cpp/lib/SimpleLoggerImpl.cc b/pulsar-client-cpp/lib/SimpleLoggerImpl.cc
new file mode 100644
index 0000000..309eb33
--- /dev/null
+++ b/pulsar-client-cpp/lib/SimpleLoggerImpl.cc
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "SimpleLoggerImpl.h"
+
+#include <iostream>
+#include <sstream>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/format.hpp>
+
+namespace pulsar {
+
+inline std::ostream &operator<<(std::ostream &s, Logger::Level level) {
+ switch (level) {
+ case Logger::DEBUG:
+ s << "DEBUG";
+ break;
+ case Logger::INFO:
+ s << "INFO ";
+ break;
+ case Logger::WARN:
+ s << "WARN ";
+ break;
+ case Logger::ERROR:
+ s << "ERROR";
+ break;
+ }
+
+ return s;
+}
+
+class SimpleLogger : public Logger {
+ std::string _logger;
+
+ public:
+ SimpleLogger(const std::string &logger) : _logger(logger) {}
+
+ bool isEnabled(Level level) { return level >= Logger::INFO; }
+
+ void log(Level level, int line, const std::string &message) {
+ std::stringstream ss;
+
+ printTimestamp(ss);
+ ss << " " << level << " " << _logger << ":" << line << " | " << message << "\n";
+
+ std::cout << ss.str();
+ std::cout.flush();
+ }
+
+ private:
+ static std::ostream &printTimestamp(std::ostream &s) {
+ boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+
+ const boost::format f =
+ boost::format("%04d-%02d-%02d %02d:%02d:%02d.%03d") % now.date().year_month_day().year %
+ now.date().year_month_day().month.as_number() % now.date().year_month_day().day.as_number() %
+ now.time_of_day().hours() % now.time_of_day().minutes() % now.time_of_day().seconds() %
+ (now.time_of_day().fractional_seconds() / 1000);
+
+ s << f.str();
+ return s;
+ }
+};
+
+Logger *SimpleLoggerFactory::getLogger(const std::string &path) {
+ // Remove all directories from filename
+ int startIdx = path.find_last_of("/");
+ int endIdx = path.find_last_of(".");
+ std::string fileName = path.substr(startIdx + 1, endIdx - startIdx - 1);
+ return new SimpleLogger(fileName);
+}
+
+LoggerFactoryPtr SimpleLoggerFactory::create() { return LoggerFactoryPtr(new SimpleLoggerFactory); }
+} // namespace pulsar
diff --git a/pulsar-client-cpp/tests/main.cc b/pulsar-client-cpp/lib/SimpleLoggerImpl.h
similarity index 77%
copy from pulsar-client-cpp/tests/main.cc
copy to pulsar-client-cpp/lib/SimpleLoggerImpl.h
index a600af3..2b81060 100644
--- a/pulsar-client-cpp/tests/main.cc
+++ b/pulsar-client-cpp/lib/SimpleLoggerImpl.h
@@ -16,11 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
-#include <LogUtils.h>
-#include <gmock/gmock.h>
-int main(int argc, char **argv) {
- LogUtils::init("log4cxx.conf");
- ::testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
-}
+#pragma once
+
+#include <pulsar/Logger.h>
+
+namespace pulsar {
+
+class SimpleLoggerFactory : public LoggerFactory {
+ public:
+ Logger* getLogger(const std::string& fileName);
+
+ static LoggerFactoryPtr create();
+};
+
+} // namespace pulsar
\ No newline at end of file
diff --git a/pulsar-client-cpp/lib/c/c_ClientConfiguration.cc b/pulsar-client-cpp/lib/c/c_ClientConfiguration.cc
index 8caf8e8..6ceaf6b 100644
--- a/pulsar-client-cpp/lib/c/c_ClientConfiguration.cc
+++ b/pulsar-client-cpp/lib/c/c_ClientConfiguration.cc
@@ -69,13 +69,31 @@ int pulsar_client_configuration_get_concurrent_lookup_request(pulsar_client_conf
return conf->conf.getConcurrentLookupRequest();
}
-void pulsar_client_configuration_set_log_conf_file_path(pulsar_client_configuration_t *conf,
- const char *logConfFilePath) {
- conf->conf.setLogConfFilePath(logConfFilePath);
-}
+class PulsarCLogger : public pulsar::Logger {
+ std::string file_;
+ pulsar_logger logger_;
+
+ public:
+ PulsarCLogger(const std::string &file, pulsar_logger logger) : file_(file), logger_(logger) {}
+
+ bool isEnabled(Level level) { return level >= pulsar::Logger::INFO; }
+
+ void log(Level level, int line, const std::string &message) {
+ logger_((pulsar_logger_level_t)level, file_.c_str(), line, message.c_str());
+ }
+};
+
+class PulsarCLoggerFactory : public pulsar::LoggerFactory {
+ pulsar_logger logger_;
+
+ public:
+ PulsarCLoggerFactory(pulsar_logger logger) : logger_(logger) {}
+
+ pulsar::Logger *getLogger(const std::string &fileName) { return new PulsarCLogger(fileName, logger_); }
+};
-const char *pulsar_client_configuration_get_log_conf_file_path(pulsar_client_configuration_t *conf) {
- return conf->conf.getLogConfFilePath().c_str();
+void pulsar_client_configuration_set_logger(pulsar_client_configuration_t *conf, pulsar_logger logger) {
+ conf->conf.setLogger(pulsar::LoggerFactoryPtr(new PulsarCLoggerFactory(logger)));
}
void pulsar_client_configuration_set_use_tls(pulsar_client_configuration_t *conf, int useTls) {
diff --git a/pulsar-client-cpp/perf/CMakeLists.txt b/pulsar-client-cpp/perf/CMakeLists.txt
index b298871..b3c8dc8 100644
--- a/pulsar-client-cpp/perf/CMakeLists.txt
+++ b/pulsar-client-cpp/perf/CMakeLists.txt
@@ -31,5 +31,5 @@ set(PERF_CONSUMER_SOURCES
add_executable(perfProducer ${PERF_PRODUCER_SOURCES})
add_executable(perfConsumer ${PERF_CONSUMER_SOURCES})
-target_link_libraries(perfProducer ${CLIENT_LIBS})
-target_link_libraries(perfConsumer ${CLIENT_LIBS})
+target_link_libraries(perfProducer pulsarShared ${CLIENT_LIBS})
+target_link_libraries(perfConsumer pulsarShared ${CLIENT_LIBS})
diff --git a/pulsar-client-cpp/perf/PerfConsumer.cc b/pulsar-client-cpp/perf/PerfConsumer.cc
index 337035e..a263c57 100644
--- a/pulsar-client-cpp/perf/PerfConsumer.cc
+++ b/pulsar-client-cpp/perf/PerfConsumer.cc
@@ -237,8 +237,6 @@ void startPerfConsumer(const Arguments& args) {
}
int main(int argc, char** argv) {
- LogUtils::init("conf/log4cxx.conf");
-
// First try to read default values from config file if present
const std::string confFile = "conf/client.conf";
std::string defaultServiceUrl;
diff --git a/pulsar-client-cpp/perf/PerfProducer.cc b/pulsar-client-cpp/perf/PerfProducer.cc
index d591d34..859d4bd 100644
--- a/pulsar-client-cpp/perf/PerfProducer.cc
+++ b/pulsar-client-cpp/perf/PerfProducer.cc
@@ -30,6 +30,7 @@ DECLARE_LOG_OBJECT()
#include <boost/accumulators/statistics/p_square_quantile.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options.hpp>
+#include <boost/thread.hpp>
namespace po = boost::program_options;
#include <iostream>
@@ -151,7 +152,7 @@ void runProducer(const Arguments& args, std::string topicName, int threadIndex,
producer.sendAsync(msg, boost::bind(sendCallback, _1, _2, Clock::now()));
boost::this_thread::interruption_point();
}
- } catch(const boost::thread_interrupted&) {
+ } catch(const boost::thread_interrupted& e) {
// Thread interruption request received, break the loop
LOG_INFO("Thread interrupted. Exiting thread.");
}
@@ -187,8 +188,6 @@ void startPerfProducer(const Arguments& args, pulsar::ProducerConfiguration &pro
}
int main(int argc, char** argv) {
- LogUtils::init("conf/log4cxx.conf");
-
std::string defaultServiceUrl;
// First try to read default values from config file if present
@@ -305,6 +304,8 @@ int main(int argc, char** argv) {
for (po::variables_map::iterator it = map.begin(); it != map.end(); ++it) {
if (it->second.value().type() == typeid(std::string)) {
LOG_INFO(it->first << ": " << it->second.as<std::string>());
+ } else if (it->second.value().type() == typeid(bool)) {
+ LOG_INFO(it->first << ": " << it->second.as<bool>());
} else if (it->second.value().type() == typeid(int)) {
LOG_INFO(it->first << ": " << it->second.as<int>());
} else if (it->second.value().type() == typeid(double)) {
@@ -355,7 +356,8 @@ int main(int argc, char** argv) {
Clock::time_point oldTime = Clock::now();
unsigned long totalMessagesProduced = 0;
- while (args.numberOfSamples--) {
+ long messagesToSend = args.numberOfSamples;
+ while (args.numberOfSamples == 0 || --messagesToSend > 0) {
std::this_thread::sleep_for(std::chrono::seconds(args.samplingPeriod));
Clock::time_point now = Clock::now();
diff --git a/pulsar-client-cpp/tests/main.cc b/pulsar-client-cpp/tests/main.cc
index a600af3..0659925 100644
--- a/pulsar-client-cpp/tests/main.cc
+++ b/pulsar-client-cpp/tests/main.cc
@@ -20,7 +20,6 @@
#include <gmock/gmock.h>
int main(int argc, char **argv) {
- LogUtils::init("log4cxx.conf");
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
--
To stop receiving notification emails like this one, please contact
mmerli@apache.org.