C++ STL Linux Logger

C++ repository can be found from https://bitbucket.org/timetopic/timetopic-logger-linux-logger-api. Example tested with Linux Ubuntu using Eclipse development IDE.

Client is written C++ STL with pthread and socket.

Example contains API for TimeToPic Events, states and ValueAbs. Messages are sent over TCPIP.

Basically:

  • Add .cpp to your project
  • Use either TimeToPicLog.h or TimeToPicLinuxLoggerAPI.h functions on your code.

or use CMake.


#define TTPLOGGING
#include "../TimeToPicLinuxLoggerAPI.h"

using namespace std;

int main() {
  cout << "TimeToPic logger tester" << endl; // prints !!!Hello World!!!

  try {
    auto &l = TimeToPicLog::instance();
    l.setClientMode(); // target will connect Logger (IP:127.0.0.1 port 5000)
    l.waitForConnection(10); // Wait that we have connection before proceeding.
    TTPLOG_POSTCODE("Test started");
    TTPLOG_FUNCTIONSCOPE; // example macro about scope logging.

    TTPLOG_POSTCODE("Test running");
    while (1) {
      int value=0;
      scopeLog("while");
      std::this_thread::sleep_for (std::chrono::seconds(1));
      l.logText(string("Message from main thread"));
    }

  }
  catch (std::exception& e){
    /* Initialization failed */
    cout << "TimeToPic logger tester failed" << endl;
    int exitVar=0;
    cin >> exitVar;
  }
  return 0;
}

TimeToPicLinuxLoggerAPI.h

(see latest version from repository)

#ifndef TIMETOPICLOGAPI_H_
#define TIMETOPICLOGAPI_H_

#include "TimeToPicLog.h"

class scopeLog {
public:
  scopeLog(string scope = "unknown") : mScope(scope) ,mLogger(TimeToPicLog::instance()) {
    mLogger.logEventStart(mScope);
  }
  ~scopeLog() {
    mLogger.logEventStop(mScope);
  }
private:
  string mScope;
  TimeToPicLog &mLogger;
};

/* #define TTPLOGGING somewhere before header if you want use these */

#ifdef TTPLOGGING

#define TTPLOG_EVENT(channel, state)                                           \
   TimeToPicLog::instance().logEvent(channel, state)

#define TTPLOG_VALUE(channel, value)                                           \
   TimeToPicLog::instance().logValue(channel, value)

#define TTPLOG_STATE(channel, state)                                           \
   TimeToPicLog::instance().logState(channel, state)

#define TTPLOG_STRING(str)  TimeToPicLog::instance().logText(str)

#define TTPLOG_POSTCODE(str)                                                   \
   TimeToPicLog::instance().logText(string("postcode ")+str)

/* Macro for reporting messaging between entitities */
#define TTPLOG_MESSAGE(source, destination, messagename)                       \
   TimeToPicLog::instance().logMessage(source, destination, messagename)

#define TTPLOG_FUNCTIONSCOPE scopeLog(__FUNCTION__)
#else
#define TTPLOG_FUNCTIONSCOPE
#define TTPLOG_EVENT
#define TTPLOG_VALUE
#define TTPLOG_STATE
#define TTPLOG_STRING
#define TTPLOG_POSTCODE
#define TTPLOG_MESSAGE
#endif

#endif // TIMETOPICLOGAPI_H_

TimeToPicLog.h

(see latest version from repository)

#ifndef TIMETOPICLOG_H_
#define TIMETOPICLOG_H_

.. code removed for readability ..

using namespace std;

struct LoggerInitFailException: public exception {
  const char * what() const throw () {
    return "TimeToPic logger initialization failed";
  }
};


class TimeToPicLog {
public:

  /* You need add 'pthread' to your libraries */

  /* Max amount of data to be added to queue */
  static const int maxLogLinesInQueue=100000;
  static const int defaultTimeToPicTcpRemoteConnectionPort=5000;

  TimeToPicLog(); // Throws LoggerInitFailException if init fails
  virtual ~TimeToPicLog();

  TimeToPicLog(TimeToPicLog const&)               = delete;
  TimeToPicLog& operator=(TimeToPicLog const&)    = delete;

  /* Create singleton item for logging */
  static TimeToPicLog & instance(); // Throws LoggerInitFailException if init fails

  /* Deletion of singleton */
  static void stopInstance();

  /* Connection setup */

  /* When object is instantiated, serverMode is set by default */

  /* When in server mode, starts listening connections. When connected
   * by remote client, forwards all data there. In case of connection lost,
   * starts listening again. */
  bool setServerMode();

  /* When in client mode, starts connecting to remote. When connected, forwards all data there.
   * In case of disconnect, start connecting again. Tries to connect perioidic basis until connection
   * is made. */

  bool setClientMode(string destinationTcpAddress, int portNumber=defaultTimeToPicTcpRemoteConnectionPort);

  /* Helper function. Blocks until connection is set up or threshold time has been elapsed */
  void waitForConnection(int maxWaitSec=10);

  /* Logging API */

  /* API for logging generic text */
  void logText(const string &logStr);

  /* API for logging event start */
  void logEventStart(const string &eventName) {
    if (eventName.empty()==false) {
      logText(eventStartPrefixStr+eventName);
    }
  }

  /* API for logging event stop */
  void logEventStop(const string &eventName) {
    if (eventName.empty()==false) {
      logText(eventStopPrefixStr+eventName);
    }
    }

  /* API for logging event value */
  void logValue(const string &valueName, double &value) {
    if (valueName.empty()==false) {

    }
  }

  /* API for logging state machine */
  void logState(const string stateMachineName, string machineNextState) {
    if (stateMachineName.empty()==false && machineNextState.empty() ==false) {

    }
  }

  /* API for logging messages between entities */
  void logMessage(const string &senderName, const string &receiverName, const string &messageName) {
    if (senderName.empty()==false && receiverName.empty() ==false && messageName.empty()==false) {

    }
  }

private:
   .. code removed for readability ..
};