bremenpl

CLogger.cpp

Jul 1st, 2015
364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.27 KB | None | 0 0
  1. #include "CLogger.h"
  2.  
  3. using namespace std;
  4.  
  5. CLogger* CLogger::mp_instance = NULL;
  6.  
  7. /*!
  8.  *  This function is called to create an instance of the class.
  9.  *  Calling the constructor publicly is not allowed. The constructor
  10.  *  is private and is only called by this Instance function.
  11.  *  @param lLevel  Log level for current object
  12.  */
  13. CLogger* CLogger::internalInstance(ElogLevel lLevel)
  14. {
  15.     // Only allow one instance of class to be generated.
  16.     if (!mp_instance)
  17.         mp_instance = new CLogger;
  18.  
  19.     mp_instance->mp_logLine = new logline_t;
  20.  
  21.     gettimeofday(&mp_instance->mp_logLine->currentTime, NULL);
  22.     mp_instance->mp_logLine->logLevel = lLevel;
  23.  
  24.     return mp_instance;
  25. }
  26.  
  27. /*!
  28.  * This method is called in order to use the methods
  29.  * within the objects.
  30.  * @param lLevel  Log level for current object
  31.  */
  32. CLoggerProxy CLogger::instance(ElogLevel lLevel)
  33. {
  34.     return CLoggerProxy(*internalInstance(lLevel));
  35. }
  36.  
  37. /*!
  38.  * \brief Starts the logging system.
  39.  *
  40.  * This method creates and opens the log file,
  41.  * then opens it and creates the threadloop for messages deque.
  42.  * @param fileName desired log file path,
  43.  * @param verbose when set true, logging will also be printed to standard output.
  44.  */
  45. bool CLogger::startLog(string fileName, bool verbose)
  46. {
  47.     if(remove(fileName.c_str()) != 0)
  48.         perror( "Error deleting file" );
  49.  
  50.     m_logFileStream.open(fileName.c_str(), ios::out | ios::app);
  51.     if (!m_logFileStream.is_open())
  52.     {
  53.         cout << "Could not open log file " << fileName << endl;
  54.         return false;
  55.     }
  56.  
  57.     m_finishLog = false;
  58.     m_verbose = verbose;
  59.     m_logStarted = true;
  60.  
  61.     gettimeofday(&m_initialTime, NULL);
  62.  
  63.     return (pthread_create(&(m_thread), NULL, threadHelper, this) == 0);
  64. }
  65.  
  66. /*!
  67.  * \brief puts a \ref logline_t object at the end of the queue
  68.  * @param s object to be added to queue
  69.  */
  70. void CLogger::push_back(logline_t* s)
  71. {
  72.     unique_lock<mutex> ul(m_mutex);
  73.     m_data.emplace_back(move(s));
  74.     m_cv.notify_all();
  75. }
  76.  
  77. /*!
  78.  * \brief takes a \ref logline_t object from the beggining of the queue
  79.  * @return first \ref logline_t object
  80.  */
  81. CLogger::logline_t CLogger::pop_front()
  82. {
  83.     unique_lock<mutex> ul(m_mutex);
  84.     m_cv.wait(ul, [this]() { return !m_data.empty(); });
  85.  
  86.     logline_t retVal = move(*m_data.front());
  87.  
  88.     delete m_data.front();
  89.     m_data.pop_front();
  90.  
  91.     return retVal;
  92. }
  93.  
  94. /*!
  95.  * \brief Sets the log level for the whole \ref CLogger object.
  96.  * If \ref m_logLine is equal or higher than set level, log
  97.  * is going to be printed.
  98.  * @param lLevel desired user define log level.
  99.  */
  100. void CLogger::setLogLevel(ElogLevel lLevel)
  101. {
  102.     m_userDefinedLogLevel = lLevel;
  103. }
  104.  
  105. /*!
  106.  * \brief Stops the logging system.
  107.  * Last final logline is being added and then the logging thread
  108.  * is being closed.
  109.  */
  110. void CLogger::stopLog()
  111. {
  112.     m_finishLog = true;
  113.     instance(ElogLevel::eNone).log << "CLogger Stop";
  114.  
  115.     pthread_join(m_thread, NULL);
  116. }
  117.  
  118. /*!
  119.  * This function should be run in the \ref CLoggerProxy destructor.
  120.  * is pushes the gathered stream to the queue.
  121.  */
  122. void CLogger::finaliseLine()
  123. {
  124.     if ((mp_logLine->logString.gcount() > 0) && !m_holdLog)
  125.         push_back(mp_logLine);
  126.     else if ((mp_logLine->logString.gcount() > 0) && m_holdLog)
  127.         m_holdLog = false;
  128.     else
  129.         delete mp_instance->mp_logLine;
  130. }
  131.  
  132. /*!
  133.  * The loop running in a separate thread. It take items of the
  134.  * log deque object (if there are any) and saves them to a file.
  135.  */
  136. void CLogger::threadLoop()
  137. {
  138.     logline_t logline;
  139.     const string logLevelsStrings[] = {"eNone", "eError", "eWarning", "eInfo", "eDebug" };
  140.  
  141.     COteestream tee;
  142.     tee.add(m_logFileStream);
  143.  
  144.     if (m_verbose)
  145.         tee.add(cout);
  146.  
  147.     int secs = 0;
  148.     int h = 0;
  149.     int m = 0;
  150.     int s = 0;
  151.  
  152.     do
  153.     {
  154.         logline = pop_front(); // waits here for new lines
  155.  
  156.         secs = logline.currentTime.tv_sec - m_initialTime.tv_sec;
  157.         h = secs / 3600;
  158.         m = ( secs % 3600 ) / 60;
  159.         s = ( secs % 3600 ) % 60;
  160.  
  161.         tee     << "["
  162.                 << setw(2) << setfill('0') << h
  163.                 << ":"
  164.                 << setw(2) << setfill('0') << m
  165.                 << ":"
  166.                 << setw(2) << setfill('0') << s
  167.                 << "."
  168.                 << setw(6) << setfill('0') << logline.currentTime.tv_usec
  169.                 << "]"
  170.                 << "["
  171.                 << logLevelsStrings[(int)logline.logLevel]
  172.                 << "] "
  173.                 << logline.logString << "\n" << flush;
  174.     }
  175.     while(!(m_finishLog && m_data.empty()));
  176.  
  177.     m_logFileStream.close();
  178. }
Advertisement
Add Comment
Please, Sign In to add comment