From ffb053fb7512a456c38030b302e88f65c1fd14de Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Fri, 9 Dec 2016 17:37:28 +0100
Subject: [PATCH] Created new file logger.

---
 common/CMakeLists.txt         |  2 +
 common/log/FileLogger.cpp     | 74 +++++++++++++++++++++++++++++++
 common/log/FileLogger.hpp     | 82 +++++++++++++++++++++++++++++++++++
 common/log/FileLoggerTest.cpp | 39 +++++++++++++++++
 4 files changed, 197 insertions(+)
 create mode 100644 common/log/FileLogger.cpp
 create mode 100644 common/log/FileLogger.hpp
 create mode 100644 common/log/FileLoggerTest.cpp

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index aaa0f14a04..065c95430e 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 0000000000..a99f6e5e76
--- /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 0000000000..9737226579
--- /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 0000000000..a629296ea7
--- /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));
+  }
+}
-- 
GitLab