Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions pulsar-client-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
Expand Down Expand Up @@ -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)
Expand All @@ -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)


Expand Down Expand Up @@ -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)
Expand Down
13 changes: 13 additions & 0 deletions pulsar-client-cpp/include/pulsar/ClientConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -105,6 +107,7 @@ class ClientConfiguration {
* Initialize the log configuration
*
* @param logConfFilePath path of the configuration file
* @deprecated
*/
ClientConfiguration& setLogConfFilePath(const std::string& logConfFilePath);

Expand All @@ -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;

Expand Down
51 changes: 51 additions & 0 deletions pulsar-client-cpp/include/pulsar/Logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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.
*/
#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
17 changes: 5 additions & 12 deletions pulsar-client-cpp/include/pulsar/c/client_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down
7 changes: 7 additions & 0 deletions pulsar-client-cpp/lib/ClientConfiguration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions pulsar-client-cpp/lib/ClientConfigurationImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct ClientConfigurationImpl {
std::string tlsTrustCertsFilePath;
bool tlsAllowInsecureConnection;
unsigned int statsIntervalInSeconds;
LoggerFactoryPtr loggerFactory;

ClientConfigurationImpl()
: authenticationPtr(AuthFactory::Disabled()),
ioThreads(1),
Expand Down
21 changes: 20 additions & 1 deletion pulsar-client-cpp/lib/ClientImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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_ =
Expand Down
41 changes: 41 additions & 0 deletions pulsar-client-cpp/lib/Log4CxxLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* 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.
*/

#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
96 changes: 96 additions & 0 deletions pulsar-client-cpp/lib/Log4cxxLogger.cc
Original file line number Diff line number Diff line change
@@ -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
Loading