/* Copyright (C) 2014 InfiniDB, Inc. 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; version 2 of the License. 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 02110-1301, USA. */ /******************************************************************************* * $Id: we_log.cpp 4504 2013-02-02 00:07:43Z bpaul $ * *******************************************************************************/ #include "we_log.h" #include "messageids.h" #include "we_define.h" #include "we_simplesyslog.h" #include "we_convertor.h" namespace WriteEngine { WriteEngine::WErrorCodes ec; // referenced as extern by chunkmanager //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ Log::Log() : m_bConsoleOutput(true), m_logFileName(""), m_errlogFileName("") { m_pid = ::getpid(); } //------------------------------------------------------------------------------ // Destructor //------------------------------------------------------------------------------ Log::~Log() { m_logFile.close(); m_errLogFile.close(); } //------------------------------------------------------------------------------ // DESCRIPTION: // Format a message to be logged // PARAMETERS: // msg - message // level - message level // oss - formatted msg // code - return status code to include in the message // RETURN: // none //------------------------------------------------------------------------------ void Log::formatMsg(const std::string& msg, MsgLevel level, std::ostringstream& oss, int code) const { // Constructing and logging the entire message as one string, should // help avoid any thread contention that could cause logging output // to be interweaved between threads. oss << Convertor::getTimeStr(); // Include thread id in log message based on debug level if (isDebug(DEBUG_2)) { oss << " (" << m_pid << ":" << pthread_self() << ") " << MSG_LEVEL_STR[level] << " : " << msg; } else { oss << " (" << m_pid << ") " << MSG_LEVEL_STR[level] << " : " << msg; } if (code > 0) oss << " [" << code << "]"; } //------------------------------------------------------------------------------ // DESCRIPTION: // Log a message to the log file and to the console. // We used to log error and critical error msgs to error log only. // But changed to log to m_logFile too, because it's easy to // forget to look at the err log. And seeing the error log msg // in the correct timeline context in the m_logFile helps to see // what else was going on when the problem occurred. // PARAMETERS: // msg - message // code - return status code to include in the message // level - message level // RETURN: // none //------------------------------------------------------------------------------ void Log::logMsg(const char* msg, int code, MsgLevel level) { std::ostringstream oss; formatMsg(msg, level, oss, code); // log error and critical msgs to syslog if (level == MSGLVL_ERROR || level == MSGLVL_CRITICAL) { { // log to log file and error log file within scope of mutex lock. // logSyslog uses SimpleSyslog which has it's own lock. boost::mutex::scoped_lock lk(m_WriteLockMutex); m_errLogFile << oss.str() << std::endl; m_logFile << oss.str() << std::endl; std::cerr << oss.str() << std::endl; } logSyslog(std::string(msg), code); } else { std::ostringstream oss2; // Format msg again without including the status code. // Only log INFO2 msgs to console if m_bConsoleOutput is TRUE; // All other msg levels always go to console. if ((level != MSGLVL_INFO2) || (m_bConsoleOutput)) formatMsg(msg, level, oss2); boost::mutex::scoped_lock lk(m_WriteLockMutex); m_logFile << oss.str() << std::endl; if ((level != MSGLVL_INFO2) || (m_bConsoleOutput)) std::cout << oss2.str() << std::endl; } } //------------------------------------------------------------------------------ // DESCRIPTION: // Set log file name // PARAMETERS: // logfile - log file name // errlogfile - error log file name // RETURN: // none //------------------------------------------------------------------------------ void Log::setLogFileName(const char* logfile, const char* errlogfile, bool consoleFlag) { m_logFileName = logfile; m_errlogFileName = errlogfile; m_bConsoleOutput = consoleFlag; m_logFile.open(m_logFileName.c_str(), std::ofstream::out | std::ofstream::app); m_errLogFile.open(m_errlogFileName.c_str(), std::ofstream::out | std::ofstream::app); } //------------------------------------------------------------------------------ // DESCRIPTION: // Log specified (error or critical) message to syslog error log. // PARAMETERS: // msg - message // statusCode - WriteEngine return status code to include in the message // RETURN: // none //------------------------------------------------------------------------------ void Log::logSyslog(const std::string& msg, int statusCode) { logging::Message::MessageID msgId = logging::M0087; switch (statusCode) { case ERR_FILE_DISK_SPACE: { msgId = logging::M0076; break; } case ERR_UNKNOWN: { msgId = logging::M0017; break; } default: { msgId = logging::M0087; break; } } logging::Message::Args errMsgArgs; errMsgArgs.add(msg); SimpleSysLog::instance()->logMsg(errMsgArgs, logging::LOG_TYPE_ERROR, msgId); } //------------------------------------------------------------------------------ // DESCRIPTION: // BUG 5022 // Close the log files with out calling d'tor. That way we can use the // object again for logging while importing another table or so // PARAMETERS: // none // RETURN: // none //------------------------------------------------------------------------------ void Log::closeLog() { m_logFile.close(); m_errLogFile.close(); } } // namespace WriteEngine