42 #include <log4cxx/basicconfigurator.h>
43 #include <log4cxx/consoleappender.h>
44 #include <log4cxx/helpers/bytearrayinputstream.h>
45 #include <log4cxx/patternlayout.h>
46 #include <log4cxx/propertyconfigurator.h>
47 #include <log4cxx/xml/domconfigurator.h>
55 #define MAX_LOG_MSG_LEN 1024
60 const char configEnv[] =
"LSST_LOG_CONFIG";
63 const char layoutPattern[] =
"%c %p: %m%n";
73 void configFromFile(std::string
const& filename) {
75 size_t dotpos = filename.find_last_of(
".");
76 if (dotpos != std::string::npos && filename.compare(dotpos, std::string::npos,
".xml") == 0) {
94 void defaultConfig() {
97 if (
const char* env = getenv(::configEnv)) {
98 if (env[0] and access(env, R_OK) == 0) {
105 log4cxx::LogString pattern(layoutPattern);
106 log4cxx::LayoutPtr layout(
new log4cxx::PatternLayout(pattern));
107 log4cxx::AppenderPtr appender(
new log4cxx::ConsoleAppender(layout));
108 auto root = log4cxx::Logger::getRootLogger();
109 root->addAppender(appender);
110 root->setLevel(log4cxx::Level::getInfo());
117 log4cxx::LoggerPtr log4cxxInit(
bool skipInit) {
124 return log4cxx::Logger::getRootLogger();
128 std::vector<std::function<void()>> mdcInitFunctions;
129 std::mutex mdcInitMutex;
135 pthread_key_create(&key,
nullptr);
152 log4cxx::LoggerPtr
const& Log::_defaultLogger(log4cxx::LoggerPtr
const& newDefault) {
153 bool isNull = newDefault == log4cxx::LoggerPtr();
156 static log4cxx::LoggerPtr _default(::log4cxxInit(!isNull));
159 _default = newDefault;
177 log4cxx::BasicConfigurator::resetConfiguration();
183 _defaultLogger(log4cxx::Logger::getRootLogger());
199 log4cxx::BasicConfigurator::resetConfiguration();
201 ::configFromFile(filename);
204 _defaultLogger(log4cxx::Logger::getRootLogger());
216 log4cxx::BasicConfigurator::resetConfiguration();
218 std::vector<unsigned char> data(properties.begin(), properties.end());
219 log4cxx::helpers::InputStreamPtr inStream(
new log4cxx::helpers::ByteArrayInputStream(data));
220 log4cxx::helpers::Properties prop;
225 _defaultLogger(log4cxx::Logger::getRootLogger());
239 std::string name = _logger->getName();
240 if (name ==
"root") {
255 if (loggername.empty()){
258 return Log(log4cxx::Logger::getLogger(loggername));
269 throw std::invalid_argument(
"lsst::log::Log::pushContext(): "
270 "empty context name is not allowed");
273 if (name.find(
'.') != std::string::npos) {
274 throw std::invalid_argument(
"lsst::log::Log::pushContext(): "
275 "multi-level contexts are not allowed: " + name);
279 std::string newName = _defaultLogger()->getName();
280 if (newName ==
"root") {
287 _defaultLogger(log4cxx::Logger::getLogger(newName));
296 log4cxx::LoggerPtr parent = _defaultLogger()->getParent();
299 _defaultLogger(parent);
311 void Log::MDC(std::string
const& key, std::string
const& value) {
312 log4cxx::MDC::put(key, value);
320 log4cxx::MDC::remove(key);
325 std::lock_guard<std::mutex> lock(mdcInitMutex);
332 ::mdcInitFunctions.push_back(std::move(
function));
343 _logger->setLevel(log4cxx::Level::toLevel(level));
350 log4cxx::LevelPtr level = _logger->getLevel();
353 levelno = level->toInt();
365 if (_logger->isEnabledFor(log4cxx::Level::toLevel(level))) {
376 log4cxx::spi::LocationInfo
const& location,
384 logMsg(level, location, msg);
390 log4cxx::spi::LocationInfo
const& location,
391 std::string
const& msg
396 void *ptr = pthread_getspecific(::pthreadKey.key);
397 if (ptr ==
nullptr) {
400 ptr =
static_cast<void*
>(&::pthreadKey);
401 pthread_setspecific(::pthreadKey.key, ptr);
403 std::lock_guard<std::mutex> lock(mdcInitMutex);
405 for (
auto& fun: mdcInitFunctions) {
411 _logger->forcedLog(level, msg, location);
static Log getDefaultLogger()
Return default logger instance, same as default constructor.
static void configure()
Explicitly configures log4cxx and initializes logging system.
static std::string getDefaultLoggerName()
Get the current default logger name.
void logMsg(log4cxx::LevelPtr level, log4cxx::spi::LocationInfo const &location, std::string const &msg)
Method used by LOGS_INFO and similar macros to process a log message.
This static class includes a variety of methods for interacting with the the logging module...
void log(log4cxx::LevelPtr level, log4cxx::spi::LocationInfo const &location, char const *fmt,...)
Method used by LOG_INFO and similar macros to process a log message with variable arguments along wit...
bool isEnabledFor(int level) const
Return whether the logging threshold of the logger is less than or equal to LEVEL.
static void MDC(std::string const &key, std::string const &value)
Places a KEY/VALUE pair in the Mapped Diagnostic Context (MDC) for the current thread.
LSST DM logging module built on log4cxx.
static void MDCRemove(std::string const &key)
Remove the value associated with KEY within the MDC.
int getLevel() const
Retrieve the logging threshold.
void setLevel(int level)
Set the logging threshold to LEVEL.
static Log getLogger(Log const &logger)
unsigned lwpID()
Function which returns LWP ID on platforms which support it.
std::string getName() const
Get the logger name associated with the Log object.
static void configure_prop(std::string const &properties)
Configures log4cxx using a string containing the list of properties, equivalent to configuring from a...
static void popContext()
Pops the last pushed name off the global hierarchical default logger name.
static void pushContext(std::string const &name)
Pushes NAME onto the global hierarchical default logger name.
static int MDCRegisterInit(std::function< void()> function)