// Return the Channel corresponding to the provided name Channel::Ptr Manager::get(const char* apChannelName) { Channel::Ptr ChannelPtr; Channel::Map::iterator iChannelPtr = mChannelMap.find(apChannelName); if (mChannelMap.end() != iChannelPtr) { ChannelPtr = iChannelPtr->second; } else { /// @todo Add a basic thread-safety security (throw if multiple threads create Loggers) ChannelPtr.reset(new Channel(apChannelName, mDefaultLevel)); mChannelMap[apChannelName] = ChannelPtr; } return ChannelPtr; }
// Output the Log to the Visual Studio debugger using OutputDebugString() void OutputDebug::output(const Channel::Ptr& aChannelPtr, const Log& aLog) const { const DateTime& time = aLog.getTime(); char buffer[256]; // uses snprintf for atomic thread-safe operation _snprintf(buffer, sizeof(buffer), "%.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.3u %-12s %s %s\n", time.year, time.month, time.day, time.hour, time.minute, time.second, time.ms, aChannelPtr->getName().c_str(), Log::toString(aLog.getSeverity()), (aLog.getStream()).str().c_str()); buffer[255] = '\0'; OutputDebugStringA(buffer); }
// Output the Log to the standard console using fprintf void OutputConsole::output(const Channel::Ptr& aChannelPtr, const Log& aLog) const { const DateTime& time = aLog.getTime(); // uses fprintf for atomic thread-safe operation #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), toWin32Attribute(aLog.getSeverity())); fprintf(stdout, "%.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.3u %-12s %s %s\n", #else // _WIN32 fprintf(stdout, "\x1B[%02um%.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.3u %-12s %s %s\x1b[39m\n", toEscapeCode(aLog.getSeverity()), #endif // _WIN32 time.year, time.month, time.day, time.hour, time.minute, time.second, time.ms, aChannelPtr->getName().c_str(), Log::toString(aLog.getSeverity()), (aLog.getStream()).str().c_str()); #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); #endif // _WIN32 fflush(stdout); }
// Output the Log to the standard console using printf void OutputFile::output(const Channel::Ptr& aChannelPtr, const Log& aLog) const { const DateTime& time = aLog.getTime(); if (mSize > mMaxSize) { rotate(); } if (nullptr != mpFile) { // uses fprintf for atomic thread-safe operation int nbWritten = fprintf(mpFile, "%.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.3u %-12s %s %s\n", time.year, time.month, time.day, time.hour, time.minute, time.second, time.ms, aChannelPtr->getName().c_str(), Log::toString(aLog.getSeverity()), (aLog.getStream()).str().c_str()); fflush(stdout); mSize += nbWritten; } }
void * logging_thread(void *arg) { Channel::Ptr ch; ch.reset(static_cast<Channel *>(arg)); /* casting argument */ print(log_debug, "Start logging thread for %s-api. Running as daemon: %s", ch->name(), ch->apiProtocol().c_str(), options.daemon() ? "yes" : "no"); // create configured api-interface vz::ApiIF::Ptr api; if (ch->apiProtocol() == "mysmartgrid") { api = vz::ApiIF::Ptr(new vz::api::MySmartGrid(ch, ch->options())); print(log_debug, "Using MSG-Api.", ch->name()); } else { api = vz::ApiIF::Ptr(new vz::api::Volkszaehler(ch, ch->options())); print(log_debug, "Using default api:", ch->name()); } //pthread_cleanup_push(&logging_thread_cleanup, &api); do { /* start thread mainloop */ try { ch->wait(); api->send(); } catch (std::exception &e) { print(log_error, "logging thread failed due to: %s", ch->name(), e.what()); } } while (options.logging()); print(log_debug, "Stop logging.! (daemon=%d)", ch->name(), options.daemon()); pthread_exit(0); //pthread_cleanup_pop(1); return NULL; }