/** * libtransport -- C++ library for easy XMPP Transports development * * Copyright (C) 2011, Jan Kaluza * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "transport/logging.h" #include "transport/config.h" #include #include #include #include #include "log4cxx/logger.h" #include "log4cxx/consoleappender.h" #include "log4cxx/patternlayout.h" #include "log4cxx/propertyconfigurator.h" #include "log4cxx/helpers/properties.h" #include "log4cxx/helpers/fileinputstream.h" #include "log4cxx/helpers/transcoder.h" #include #include #ifndef WIN32 #include "sys/signal.h" #include #include #include #include "libgen.h" #else #include #endif using namespace boost::filesystem; using namespace log4cxx; namespace Transport { namespace Logging { static LoggerPtr root; static void initLogging(Config *config, std::string key) { if (CONFIG_STRING(config, key).empty()) { root = log4cxx::Logger::getRootLogger(); #ifdef WIN32 root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); #else root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); #endif } else { log4cxx::helpers::Properties p; log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(config, key)); p.load(istream); LogString pid, jid; log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); log4cxx::helpers::Transcoder::decode(CONFIG_STRING(config, "service.jid"), jid); #ifdef WIN32 p.setProperty(L"pid", pid); p.setProperty(L"jid", jid); #else p.setProperty("pid", pid); p.setProperty("jid", jid); #endif std::string dir; BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) { if (boost::ends_with(prop, ".File")) { log4cxx::helpers::Transcoder::encode(p.get(prop), dir); boost::replace_all(dir, "${jid}", jid); break; } } if (!dir.empty()) { // create directories try { boost::filesystem::create_directories( boost::filesystem::path(dir).parent_path().string() ); } catch (...) { std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n"; } #ifndef WIN32 if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) { struct group *gr; if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) { std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n"; } struct passwd *pw; if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) { std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n"; } chown(dir.c_str(), pw->pw_uid, gr->gr_gid); } #endif } log4cxx::PropertyConfigurator::configure(p); } } void initBackendLogging(Config *config) { initLogging(config, "logging.backend_config"); } void initMainLogging(Config *config) { initLogging(config, "logging.config"); } } }