patterncppMinor
Simple, encapsulated C++ logger that can deal with fork/exec situations
Viewed 0 times
cansimpleforkloggerwithdealthatexecencapsulatedsituations
Problem
Motivation: for whatever reason, some of the available 3rd party logging libraries don't really deal with programs that get fork'ed/exectuted well. For instance,
This class attempts to be a simple logger for programs that get forked/exec'ed.
For locking, I chose to use a boost interprocess mutex rather than a file lock, because if a child process gets stuck with the lock taken out, restarting the parent process will destroy the current mutex and create a new one.
I'm looking for style, performance and viability feedback. I've tested it and it seems to work well enough.
```
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const char *kLoggerSegmentName = "MPLLoggerSeg";
static const char *kLoggerMutexName= "MPLLoggerIPCMutex";
enum LogLevel { MPLTRACE, MPLDEBUG, MPLINFO, MPLWARN, MPLERROR, MPLFATAL };
class MultiProcessLogger {
private:
LogLevel fLoggingLevel;
bool fEnabled;
bool fParent;
std::ofstream fLogFile;
inline void writeToFile(std::string &msg) {
using namespace boost::interprocess;
managed_shared_memory segment(open_only, kLoggerSegmentName);
interprocess_sharable_mutex *mutex = segment.find(kLoggerMutexName).first;
scoped_lock lock(*mutex);
fLogFile ";
case MPLDEBUG:
return "";
case MPLINFO:
return "";
case MPLWARN:
return "";
case MPLERROR:
return "";
case MPLFATAL:
return "";
default:
return "";
}
}
void destroySharedMemory() {
using namespace boost::interprocess;
try
{
shared_memory_object::remove(kLoggerSegmentName);
} catch (...) {
boost::log creates some static state that can cause deadlocks if the program using it gets forked.This class attempts to be a simple logger for programs that get forked/exec'ed.
For locking, I chose to use a boost interprocess mutex rather than a file lock, because if a child process gets stuck with the lock taken out, restarting the parent process will destroy the current mutex and create a new one.
I'm looking for style, performance and viability feedback. I've tested it and it seems to work well enough.
```
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const char *kLoggerSegmentName = "MPLLoggerSeg";
static const char *kLoggerMutexName= "MPLLoggerIPCMutex";
enum LogLevel { MPLTRACE, MPLDEBUG, MPLINFO, MPLWARN, MPLERROR, MPLFATAL };
class MultiProcessLogger {
private:
LogLevel fLoggingLevel;
bool fEnabled;
bool fParent;
std::ofstream fLogFile;
inline void writeToFile(std::string &msg) {
using namespace boost::interprocess;
managed_shared_memory segment(open_only, kLoggerSegmentName);
interprocess_sharable_mutex *mutex = segment.find(kLoggerMutexName).first;
scoped_lock lock(*mutex);
fLogFile ";
case MPLDEBUG:
return "";
case MPLINFO:
return "";
case MPLWARN:
return "";
case MPLERROR:
return "";
case MPLFATAL:
return "";
default:
return "";
}
}
void destroySharedMemory() {
using namespace boost::interprocess;
try
{
shared_memory_object::remove(kLoggerSegmentName);
} catch (...) {
Solution
- 512 is really a small fixed-size buffer for the formatted message (seriously)
- Given all the other stuff the function has to do, I'd go with a dynamic buffer here as well. (Calling vsnprintf with
0as buffer size should tell you how much you need.
- the
logfunction seems horribly inefficient: Creating the facet each time, multipleappendwithout preallocation
- Just use a single
stringstreamfor the wholelogMessage
Context
StackExchange Code Review Q#69130, answer score: 2
Revisions (0)
No revisions yet.