Online Book Reader

Home Category

Professional C__ - Marc Gregoire [483]

By Root 1524 0
inMessage,

const std::string& inLogLevel);

// Logs a vector of messages at the given log level

static void log(const std::vector& inMessages,

const std::string& inLogLevel);

// Closes the log file

static void teardown();

protected:

static void init();

static const char* const kLogFileName;

static bool sInitialized;

static std::ofstream sOutputStream;

private:

Logger() {}

};

Code snippet from StaticLogger\Logger.h

The implementation of the Logger class is fairly straightforward. The sInitialized static member is checked within each logging call to make sure that the init() method has been called to open the log file. Once the log file has been opened, each log message is written to it with the log level prepended.

#include

#include "Logger.h"

using namespace std;

const string Logger::kLogLevelDebug = "DEBUG";

const string Logger::kLogLevelInfo = "INFO";

const string Logger::kLogLevelError = "ERROR";

const char* const Logger::kLogFileName = "log.out";

bool Logger::sInitialized = false;

ofstream Logger::sOutputStream;

void Logger::log(const string& inMessage, const string& inLogLevel)

{

if (!sInitialized) {

init();

}

// Print the message and flush the stream with endl.

sOutputStream << inLogLevel << ": " << inMessage << endl;

}

void Logger::log(const vector& inMessages, const string& inLogLevel)

{

for (size_t i = 0; i < inMessages.size(); i++) {

log(inMessages[i], inLogLevel);

}

}

void Logger::teardown()

{

if (sInitialized) {

sOutputStream.close();

sInitialized = false;

}

}

void Logger::init()

{

if (!sInitialized) {

sOutputStream.open(kLogFileName, ios_base::app);

if (!sOutputStream.good()) {

throw runtime_error("Unable to initialize the Logger!");

}

sInitialized = true;

}

}

Code snippet from StaticLogger\Logger.cpp

To focus on the actual singleton pattern, this implementation uses a hardcoded file name. Of course, in production quality software, this file name should be configurable by the user, and you should not use relative paths, but fully qualified paths, for example, by retrieving the temporary directory for your OS.

Access-Controlled Singleton

Object-oriented purists (Warning: They are out there, and they may work at your company!) might scoff at the static class solution to the singleton problem. Since you can’t instantiate a Logger object, you can’t build a hierarchy of loggers and make use of polymorphism. Such a hierarchy is rarely employed in the singleton case, but it is a valid drawback. Perhaps more significantly, as a result of using entirely static methods, there is no object orientation at all. This also means that there is no way to invoke a destructor. The static version of the Logger class requires the programmer to explicitly call the teardown() method. This is a serious defect. The class built in the previous example is essentially a collection of C-style functions, not a cohesive class.

To build a true singleton in C++, you can use the access control mechanisms as well as the static keyword. With this approach, an actual Logger object exists at run time, and the class enforces that exactly one exists. Clients can always get a hold of that object through a static method called instance(). The class definition looks like this:

#include

#include

#include

#include

// Definition of a true singleton logger class.

class Logger

{

public:

static const std::string kLogLevelDebug;

static const std::string kLogLevelInfo;

static const std::string kLogLevelError;

// Returns a reference to the singleton Logger object

static Logger& instance();

// Logs a single message at the given log level

void log(const std::string& inMessage,

const std::string& inLogLevel);

// Logs a vector of messages at the given log level

void log(const std::vector& inMessages,

const std::string& inLogLevel);

protected:

// Static variable for the one-and-only instance

static Logger sInstance;

// Constant for the filename

static const char* const kLogFileName;

//

Return Main Page Previous Page Next Page

®Online Book Reader