diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index aaa0f14a0493aef0e52c51c6a6b5c6593eb10582..065c95430ee0f33a06f3f51ad0ccfe130d7e5082 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -91,6 +91,7 @@ set (COMMON_LIB_SRC_FILES exception/TimeOut.cpp exception/XrootCl.cpp log/DummyLogger.cpp + log/FileLogger.cpp log/LogContext.cpp log/Logger.cpp log/LogLevel.cpp @@ -147,6 +148,7 @@ set (COMMON_UNIT_TESTS_LIB_SRC_FILES dataStructures/ArchiveFileTest.cpp dataStructures/StorageClassTest.cpp processCap/SmartCapTest.cpp + log/FileLoggerTest.cpp log/LogContextTest.cpp log/LogLevelTest.cpp log/ParamTest.cpp diff --git a/common/log/FileLogger.cpp b/common/log/FileLogger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a99f6e5e7630ed3ae2a57f9258bdb6a5f98d8cd9 --- /dev/null +++ b/common/log/FileLogger.cpp @@ -0,0 +1,74 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2015 CERN + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#include "common/log/FileLogger.hpp" +#include "common/threading/MutexLocker.hpp" +#include "common/exception/Errnum.hpp" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +namespace cta { +namespace log { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +FileLogger::FileLogger(const std::string &programName, const std::string &filePath, + const int logMask): + Logger(programName, logMask) { + m_fd = ::open(filePath.c_str(), O_APPEND | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP); + cta::exception::Errnum::throwOnMinusOne(m_fd, + std::string("In FileLogger::FileLogger(): failed to open log file: ") + filePath); +} + +//------------------------------------------------------------------------------ +// destructor +//------------------------------------------------------------------------------ +FileLogger::~FileLogger() { + if (-1 != m_fd) { + ::close(m_fd); + } +} + +//------------------------------------------------------------------------------ +// prepareForFork +//------------------------------------------------------------------------------ +void FileLogger::prepareForFork() { +} + +//----------------------------------------------------------------------------- +// reducedSyslog +//----------------------------------------------------------------------------- +void FileLogger::reducedSyslog(const std::string & msg) { + if (-1 == m_fd) + throw cta::exception::Exception("In FileLogger::reducedSyslog(): file is not properly initialized"); + // Prepare the string to print (for size) + std::string m = msg.substr(0, m_maxMsgLen); + + // enter critical section + threading::MutexLocker lock(m_mutex); + + // Append the message to the file + cta::exception::Errnum::throwOnMinusOne(::write(m_fd, m.c_str(), m.size()), + "In FileLogger::reducedSyslog(): failed to write to file"); +} + +} // namespace log +} // namespace cta \ No newline at end of file diff --git a/common/log/FileLogger.hpp b/common/log/FileLogger.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9737226579465bce615850711ce14bb02d2c54da --- /dev/null +++ b/common/log/FileLogger.hpp @@ -0,0 +1,82 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2015 CERN + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "common/log/Logger.hpp" +#include "common/threading/Mutex.hpp" + +namespace cta { +namespace log { + +/** + * Class implementaing the API of the CASTOR logging system. + */ +class FileLogger: public Logger { +public: + + /** + * Constructor + * + * @param programName The name of the program to be prepended to every log + * message. + * @param filePath path to the log file. + * @param logMask The log mask. + */ + FileLogger(const std::string &programName, const std::string &filePath, + const int logMask); + + /** + * Destructor. + */ + ~FileLogger(); + + /** + * Prepares the logger object for a call to fork(). + * + * No further calls to operator() should be made after calling this + * method until the call to fork() has completed. + */ + void prepareForFork() ; + +protected: + + /** + * Mutex used to protect the critical section of the StringLogger + * object. + */ + threading::Mutex m_mutex; + + /** + * The output file handle. + */ + int m_fd=-1; + + /** + * A reduced version of syslog. This method is able to set the message + * timestamp. This is necessary when logging messages asynchronously of there + * creation, such as when retrieving logs from the DB. + * + * @param msg The message to be logged. + */ + void reducedSyslog(const std::string & msg); + +}; // class StringLogger + +} // namespace log +} // namespace cta diff --git a/common/log/FileLoggerTest.cpp b/common/log/FileLoggerTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a629296ea7adcb94ebaf36dc83715f8558e849f5 --- /dev/null +++ b/common/log/FileLoggerTest.cpp @@ -0,0 +1,39 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2015 CERN + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#include "FileLogger.hpp" +#include "tests/TempFile.hpp" + +#include <gtest/gtest.h> +#include <fstream> +#include <sstream> + +using namespace cta::log; + +namespace unitTests { + TEST(cta_log_FileLogger, basicTest) { + std::string jat = "Just a test"; + TempFile tf; + FileLogger fl("cta_log_StringLogger", tf.path(), DEBUG); + fl(INFO, jat); + std::ifstream ifs(tf.path()); + std::stringstream res; + res << ifs.rdbuf(); + ASSERT_NE(std::string::npos, res.str().find(jat)); + } +}