void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *format, va_list args) { LogChannel *log = log_[type]; if (level > log->GetLevel() || !log->IsEnabled() || !log->HasListeners()) return; std::lock_guard<std::mutex> lk(log_lock_); static const char level_to_char[8] = "-NEWIDV"; char formattedTime[13]; Common::Timer::GetTimeFormatted(formattedTime); #ifdef _WIN32 static const char sep = '\\'; #else static const char sep = '/'; #endif const char *fileshort = strrchr(file, sep); if (fileshort != NULL) { do --fileshort; while (fileshort > file && *fileshort != sep); if (fileshort != file) file = fileshort + 1; } char msg[MAX_MSGLEN]; char *msgPos = msg; size_t prefixLen; if (hleCurrentThreadName != NULL) { prefixLen = snprintf(msgPos, MAX_MSGLEN, "%s %-12.12s %c[%s]: %s:%d ", formattedTime, hleCurrentThreadName, level_to_char[(int)level], log->GetShortName(), file, line); } else { prefixLen = snprintf(msgPos, MAX_MSGLEN, "%s %s:%d %c[%s]: ", formattedTime, file, line, level_to_char[(int)level], log->GetShortName()); } msgPos += prefixLen; size_t space = MAX_MSGLEN - prefixLen - 2; size_t neededBytes = vsnprintf(msgPos, space, format, args); if (neededBytes > space) { // Cut at the end. msg[MAX_MSGLEN - 2] = '\n'; msg[MAX_MSGLEN - 1] = '\0'; } else { // Plenty of space left. msgPos[neededBytes] = '\n'; msgPos[neededBytes + 1] = '\0'; } log->Trigger(level, msg); }
void LogConfigScreen::CreateViews() { using namespace UI; I18NCategory *di = GetI18NCategory("Dialog"); I18NCategory *dev = GetI18NCategory("Developer"); root_ = new ScrollView(ORIENT_VERTICAL); LinearLayout *vert = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); vert->SetSpacing(0); LinearLayout *topbar = new LinearLayout(ORIENT_HORIZONTAL); topbar->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack); topbar->Add(new Choice(di->T("Toggle All")))->OnClick.Handle(this, &LogConfigScreen::OnToggleAll); topbar->Add(new Choice(dev->T("Log Level")))->OnClick.Handle(this, &LogConfigScreen::OnLogLevel); vert->Add(topbar); vert->Add(new ItemHeader(dev->T("Logging Channels"))); LogManager *logMan = LogManager::GetInstance(); int cellSize = 400; UI::GridLayoutSettings gridsettings(cellSize, 64, 5); gridsettings.fillCells = true; GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); for (int i = 0; i < LogManager::GetNumChannels(); i++) { LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i; LogChannel *chan = logMan->GetLogChannel(type); LinearLayout *row = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(cellSize - 50, WRAP_CONTENT)); row->SetSpacing(0); row->Add(new CheckBox(&chan->enable_, "", "", new LinearLayoutParams(50, WRAP_CONTENT))); row->Add(new PopupMultiChoice(&chan->level_, chan->GetFullName(), logLevelList, 1, 6, 0, screenManager(), new LinearLayoutParams(1.0))); grid->Add(row); } }
void GurobiBackend::initialize(unsigned int numVariables, VariableType variableType) { if (gurobilog.getLogLevel() >= Debug) setVerbose(true); else setVerbose(false); _numVariables = numVariables; // delete previous variables if (_variables) delete[] _variables; // add new variables to the model if (variableType == Binary) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " binary variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_BINARY); _model.update(); } else if (variableType == Continuous) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " continuous variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_CONTINUOUS); _model.update(); // remove default lower bound on variables for (int i = 0; i < _numVariables; i++) _variables[i].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } else if (variableType == Integer) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " integer variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_INTEGER); _model.update(); // remove default lower bound on variables for (int i = 0; i < _numVariables; i++) _variables[i].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } LOG_DEBUG(gurobilog) << "creating " << _numVariables << " ceofficients" << std::endl; }
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char *format, va_list args) { std::lock_guard<std::mutex> lk(log_lock_); char msg[MAX_MSGLEN * 2]; LogChannel *log = log_[type]; if (!log || !log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) return; static const char level_to_char[8] = "-NEWIDV"; char formattedTime[13]; Common::Timer::GetTimeFormatted(formattedTime); #ifdef _DEBUG #ifdef _WIN32 static const char sep = '\\'; #else static const char sep = '/'; #endif const char *fileshort = strrchr(file, sep); if (fileshort != NULL) { do --fileshort; while (fileshort > file && *fileshort != sep); if (fileshort != file) file = fileshort + 1; } #endif char *msgPos = msg; if (hleCurrentThreadName != NULL) { msgPos += sprintf(msgPos, "%s %-12.12s %c[%s]: %s:%d ", formattedTime, hleCurrentThreadName, level_to_char[(int)level], log->GetShortName(), file, line); } else { msgPos += sprintf(msgPos, "%s %s:%d %c[%s]: ", formattedTime, file, line, level_to_char[(int)level], log->GetShortName()); } msgPos += vsnprintf(msgPos, MAX_MSGLEN, format, args); // This will include the null terminator. memcpy(msgPos, "\n", sizeof("\n")); log->Trigger(level, msg); }
void GurobiBackend::initialize( unsigned int numVariables, VariableType defaultVariableType, const std::map<unsigned int, VariableType>& specialVariableTypes) { if (gurobilog.getLogLevel() >= Debug) setVerbose(true); else setVerbose(false); setMIPGap(optionGurobiMIPGap); if (optionGurobiMIPFocus.as<unsigned int>() <= 3) setMIPGap(optionGurobiMIPGap); else LOG_ERROR(gurobilog) << "Invalid value for MPI focus!" << std::endl; setNumThreads(optionGurobiNumThreads); _numVariables = numVariables; // delete previous variables if (_variables) delete[] _variables; // add new variables to the model if (defaultVariableType == Binary) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " binary variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_BINARY); _model.update(); } else if (defaultVariableType == Continuous) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " continuous variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_CONTINUOUS); _model.update(); // remove default lower bound on variables for (unsigned int i = 0; i < _numVariables; i++) _variables[i].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } else if (defaultVariableType == Integer) { LOG_DEBUG(gurobilog) << "creating " << _numVariables << " integer variables" << std::endl; _variables = _model.addVars(_numVariables, GRB_INTEGER); _model.update(); // remove default lower bound on variables for (unsigned int i = 0; i < _numVariables; i++) _variables[i].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } LOG_DEBUG(gurobilog) << "setting special variable types" << std::endl; // handle special variable types unsigned int v; VariableType type; foreach (boost::tie(v, type), specialVariableTypes) { char t = (type == Binary ? 'B' : (type == Integer ? 'I' : 'C')); LOG_ALL(gurobilog) << "changing type of variable " << v << " to " << t << std::endl; _variables[v].set(GRB_CharAttr_VType, t); if (type == Integer || type == Continuous) { // remove bounds, which might have been set by the default variable // type being binary previously _variables[v].set(GRB_DoubleAttr_LB, -GRB_INFINITY); _variables[v].set(GRB_DoubleAttr_UB, GRB_INFINITY); } }
bool LogManager::IsEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type) { LogChannel *log = log_[type]; if (level > log->GetLevel() || !log->IsEnabled() || !log->HasListeners()) return false; return true; }
void LogManager::init() { // set global log level if (!logLevel) { setGlobalLogLevel(User); out.setLogLevel(User); } else { LOG_DEBUG(out) << "[LogManager] " << logLevel.getLongParam() << " command-line option detected" << std::endl; std::string verbosity = logLevel; setGlobalLogLevel(getLogLevel(verbosity)); LOG_DEBUG(out) << "[LogManager] Loglevel set to \"" << verbosity << "\"" << std::endl; } if (showChannels) { printChannels(); exit(0); } // read from program options Logger::showChannelPrefix(showChannelPrefix); Logger::showThreadId(showThreadId); // set channel log levels if (channelLevel) { LOG_DEBUG(out) << "[LogManager] " << channelLevel.getLongParam() << " command-line option detected" << std::endl; std::string channelLevels = channelLevel; while (channelLevels.length() > 0) { size_t pos_eq = channelLevels.find_first_of("="); LOG_ALL(out) << "[LogManager] Found '=' at " << pos_eq << std::endl; if (pos_eq == std::string::npos) { LOG_ERROR(out) << "[LogManager] Invalid " << channelLevel.getLongParam() << " syntax." << std::endl; util::ProgramOptions::printUsage(); BOOST_THROW_EXCEPTION(UsageError() << error_message("[LogManager] Invalid command line syntax")); } std::string name = channelLevels.substr(0, pos_eq); channelLevels = channelLevels.substr(pos_eq + 1, channelLevels.length() - 1); std::string level; size_t pos_co = channelLevels.find_first_of(","); if (pos_co == std::string::npos) { LOG_ALL(out) << "[LogManager] no further channels" << std::endl; level = channelLevels.substr(0, channelLevels.length()); channelLevels = ""; } else { LOG_ALL(out) << "[LogManager] ',' detected, there are further channels at " << pos_co << std::endl; level = channelLevels.substr(0, pos_co); channelLevels = channelLevels.substr(pos_co + 1, channelLevels.length() - 1); LOG_ALL(out) << "[LogManager] remaining argument " << channelLevels << std::endl; } std::set<LogChannel*> channels = getChannels(name); for (channel_it i = channels.begin(); i != channels.end(); i++) (*i)->setLogLevel(getLogLevel(level)); LOG_DEBUG(out) << "[LogManager] log-level of channel \"" << name << "\" set to \"" << level << "\"" << std::endl; } } // redirect channels to files if (channelToFile) { LOG_DEBUG(out) << "[LogManager] " << channelToFile.getLongParam() << " command-line option detected" << std::endl; std::string channelFiles = channelToFile; while (channelFiles.length() > 0) { size_t pos_eq = channelFiles.find_first_of("="); if (pos_eq == std::string::npos) { LOG_ERROR(out) << "[LogManager] Invalid " << channelToFile.getLongParam() << " syntax." << std::endl; util::ProgramOptions::printUsage(); BOOST_THROW_EXCEPTION(UsageError() << error_message("[LogManager] Invalid command line syntax")); } std::string name = channelFiles.substr(0, pos_eq); channelFiles = channelFiles.substr(pos_eq + 1, channelFiles.length() - 1); std::string file; size_t pos_co = channelFiles.find_first_of(","); if (pos_co == std::string::npos) { file = channelFiles.substr(0, channelFiles.length()); channelFiles = ""; } else { file = channelFiles.substr(0, pos_co); channelFiles = channelFiles.substr(pos_co + 1, channelFiles.length() - 1); } std::set<LogChannel*> channels = getChannels(name); for (channel_it i = channels.begin(); i != channels.end(); i++) (*i)->redirectToFile(file); LOG_DEBUG(out) << "[LogManager] channel \"" << name << "\" redirected to file \"" << file << "\"" << std::endl; } } #ifdef HAVE_GIT_SHA1 LOG_USER(out) << "[LogManager] git sha1 of this build: " << __git_sha1 << std::endl; #endif }
namespace logger { // Define command line options util::ProgramOption logLevel( util::_long_name = "log-level", util::_short_name = "v", util::_description_text = "Specifies the level of verbosity. " "Valid values for level are: \"none\" (no ouput at all), " "\"error\" (error messages only), " "\"user\" (useful information, default setting), " "\"debug\" (internal information used for debugging) " "and \"all\" (maximum verbosity).\n" "See section on logging for more options.", util::_argument_sketch = "level"); util::ProgramOption showChannels( util::_module = "Logging", util::_long_name = "show-log-channels", util::_description_text = "Prints all avalaible log-channels. Log-channels are used to " "collect logging messages belonging to certain units of the " "program so that they can be adjusted individually. If " "you leave everything as it is, log-channel messages are handled " "like any other log message the program."); util::ProgramOption channelLevel( util::_module = "Logging", util::_long_name = "channels-log-level", util::_short_name = "V", util::_description_text = "Sets the log level for certain log-channels independent " "of the global log level.\n" "levels syntax: channel1=loglevel1,channel2=loglevel2,...\n" "For a list of possible channels type " "\"--show-log-channels\".", util::_argument_sketch = "levels"); util::ProgramOption channelToFile( util::_module = "Logging", util::_long_name = "log-file-c", util::_description_text = "Redirects the output of certain log-channels to files.\n" "files syntax: channel1=file1,channel2=file2,...\n" "For a list of possible channels type " "\"--show-log-channels\".", util::_argument_sketch = "files"); util::ProgramOption showChannelPrefix( util::_module = "Logging", util::_long_name = "show-channel-prefix", util::_description_text = "Show the channel prefix for every line of output." "True by default.", util::_default_value = true); util::ProgramOption showThreadId( util::_module = "Logging", util::_long_name = "show-thread-id", util::_description_text = "Show the thread id in the channel prefix for every line of output." "False by default."); Logger glutton(0, ""); // Initialize global logging-streams: LogLevel error = Error; LogLevel user = User; LogLevel debug = Debug; LogLevel all = All; LogChannel out("default"); // Declare static objects std::map<std::string, std::filebuf*> LogFileManager::filebuffers; LogLevel LogManager::globalLogLevel = User; LogFileManager LogChannel::logFileManager; std::set<LogChannel*>* LogChannel::logChannels = 0; LoggerCleanup loggerCleanup; // Implementation - LogChannel LogChannel::LogChannel(std::string channelName, std::string prefix) : _channelName(channelName), _prefix(prefix), _error(std::cerr.rdbuf(), _prefix), _user(std::cout.rdbuf(), _prefix), _debug(std::cout.rdbuf(), _prefix), _all(std::cout.rdbuf(), _prefix), _level(Global) { getChannels()->insert(this); } std::set<LogChannel*>* LogChannel::getChannels() { if (logChannels == 0) logChannels = new std::set<LogChannel*>(); return logChannels; } Logger& LogChannel::operator()(LogLevel level) { LogLevel myLevel = (_level == Global ? LogManager::getGlobalLogLevel() : _level); switch (level) { case Error: if (myLevel >= Error) return _error; break; case User: if (myLevel >= User) return _user; break; case Debug: if (myLevel >= Debug) return _debug; break; case All: if (myLevel >= All) return _all; break; default: break; } return glutton; } void LogChannel::setLogLevel(LogLevel level) { _level = level; } const LogLevel& LogChannel::getLogLevel() { if (_level == Global) return LogManager::getGlobalLogLevel(); return _level; } void LogChannel::redirectToFile(std::string filename) { Logger fileLogger(LogFileManager::openFile(filename), _prefix); _error = fileLogger; _user = fileLogger; _debug = fileLogger; _all = fileLogger; } // Implementation - LogFileManager LogFileManager::~LogFileManager() { std::map<std::string, std::filebuf*>::iterator i; for (i = filebuffers.begin(); i != filebuffers.end(); i++) { (*i).second->close(); delete (*i).second; } } std::filebuf* LogFileManager::openFile(std::string filename) { if (filebuffers.find(filename) != filebuffers.end()) return filebuffers[filename]; std::filebuf* filebuffer = new std::filebuf(); if (!filebuffer->open(filename.c_str(), std::ios_base::out)) { LOG_ERROR(out) << "[LogFileManager] Unable to open \"" << filename << "\"" << std::endl; BOOST_THROW_EXCEPTION(IOError() << error_message(std::string("[LogFileManager] Attempt to open file \"") + filename + "\" failed.")); } filebuffers[filename] = filebuffer; return filebuffer; } // Implementation - Logger boost::mutex Logger::FlushMutex; bool Logger::_showChannelPrefix = true; bool Logger::_showThreadId = false; Logger::Logger(std::streambuf* streamBuffer, const std::string& prefix) : std::ostream(streamBuffer), _prefix(prefix) { // Empty } Logger::Logger(Logger& logger, const std::string& prefix) : std::ostream(logger.rdbuf()), _prefix(prefix) { // Empty } Logger& Logger::operator=(const Logger& logger) { rdbuf(logger.rdbuf()); return *this; } void LogManager::init() { // set global log level if (!logLevel) { setGlobalLogLevel(User); out.setLogLevel(User); } else { LOG_DEBUG(out) << "[LogManager] " << logLevel.getLongParam() << " command-line option detected" << std::endl; std::string verbosity = logLevel; setGlobalLogLevel(getLogLevel(verbosity)); LOG_DEBUG(out) << "[LogManager] Loglevel set to \"" << verbosity << "\"" << std::endl; } if (showChannels) { printChannels(); exit(0); } // read from program options Logger::showChannelPrefix(showChannelPrefix); Logger::showThreadId(showThreadId); // set channel log levels if (channelLevel) { LOG_DEBUG(out) << "[LogManager] " << channelLevel.getLongParam() << " command-line option detected" << std::endl; std::string channelLevels = channelLevel; while (channelLevels.length() > 0) { size_t pos_eq = channelLevels.find_first_of("="); LOG_ALL(out) << "[LogManager] Found '=' at " << pos_eq << std::endl; if (pos_eq == std::string::npos) { LOG_ERROR(out) << "[LogManager] Invalid " << channelLevel.getLongParam() << " syntax." << std::endl; util::ProgramOptions::printUsage(); BOOST_THROW_EXCEPTION(UsageError() << error_message("[LogManager] Invalid command line syntax")); } std::string name = channelLevels.substr(0, pos_eq); channelLevels = channelLevels.substr(pos_eq + 1, channelLevels.length() - 1); std::string level; size_t pos_co = channelLevels.find_first_of(","); if (pos_co == std::string::npos) { LOG_ALL(out) << "[LogManager] no further channels" << std::endl; level = channelLevels.substr(0, channelLevels.length()); channelLevels = ""; } else { LOG_ALL(out) << "[LogManager] ',' detected, there are further channels at " << pos_co << std::endl; level = channelLevels.substr(0, pos_co); channelLevels = channelLevels.substr(pos_co + 1, channelLevels.length() - 1); LOG_ALL(out) << "[LogManager] remaining argument " << channelLevels << std::endl; } std::set<LogChannel*> channels = getChannels(name); for (channel_it i = channels.begin(); i != channels.end(); i++) (*i)->setLogLevel(getLogLevel(level)); LOG_DEBUG(out) << "[LogManager] log-level of channel \"" << name << "\" set to \"" << level << "\"" << std::endl; } } // redirect channels to files if (channelToFile) { LOG_DEBUG(out) << "[LogManager] " << channelToFile.getLongParam() << " command-line option detected" << std::endl; std::string channelFiles = channelToFile; while (channelFiles.length() > 0) { size_t pos_eq = channelFiles.find_first_of("="); if (pos_eq == std::string::npos) { LOG_ERROR(out) << "[LogManager] Invalid " << channelToFile.getLongParam() << " syntax." << std::endl; util::ProgramOptions::printUsage(); BOOST_THROW_EXCEPTION(UsageError() << error_message("[LogManager] Invalid command line syntax")); } std::string name = channelFiles.substr(0, pos_eq); channelFiles = channelFiles.substr(pos_eq + 1, channelFiles.length() - 1); std::string file; size_t pos_co = channelFiles.find_first_of(","); if (pos_co == std::string::npos) { file = channelFiles.substr(0, channelFiles.length()); channelFiles = ""; } else { file = channelFiles.substr(0, pos_co); channelFiles = channelFiles.substr(pos_co + 1, channelFiles.length() - 1); } std::set<LogChannel*> channels = getChannels(name); for (channel_it i = channels.begin(); i != channels.end(); i++) (*i)->redirectToFile(file); LOG_DEBUG(out) << "[LogManager] channel \"" << name << "\" redirected to file \"" << file << "\"" << std::endl; } } #ifdef HAVE_GIT_SHA1 LOG_USER(out) << "[LogManager] git sha1 of this build: " << __git_sha1 << std::endl; #endif } void LogManager::setGlobalLogLevel(LogLevel level) { globalLogLevel = level; } const LogLevel& LogManager::getGlobalLogLevel() { return globalLogLevel; } LogLevel LogManager::getLogLevel(std::string strLevel) { if (strLevel == "all") return All; else if (strLevel == "user") return User; else if (strLevel == "debug") return Debug; else if (strLevel == "error") return Error; else if (strLevel == "none") return Quiet; else { LOG_ERROR(out) << "[Logger] Unknown log level \"" << strLevel << "\"." << std::endl; util::ProgramOptions::printUsage(); BOOST_THROW_EXCEPTION(UsageError() << error_message("[Logger] Invalid log level")); } } std::set<LogChannel*> LogManager::getChannels(std::string channelName) { std::set<LogChannel*> channels; for (channel_it i = LogChannel::getChannels()->begin(); i != LogChannel::getChannels()->end(); i++) { if ( (*i)->getName() == channelName) channels.insert(*i); } if (channels.size() > 0) return channels; LOG_ERROR(out) << "[LogManager] No channel \"" << channelName << "\" available." << std::endl; printChannels(); BOOST_THROW_EXCEPTION(UsageError() << error_message(std::string("[LogManager] Invalid channel name: ") + channelName)); } void LogManager::printChannels() { if (LogChannel::getChannels()->size() == 0) { LOG_USER(out) << "No output channels for this application available." << std::endl; return; } std::string prevChannelName = ""; LOG_USER(out) << std::endl << "Valid output channels are:" << std::endl << "\t"; for (channel_it i = LogChannel::getChannels()->begin(); i != LogChannel::getChannels()->end(); i++) { if ((*i)->getName() != prevChannelName) { LOG_USER(out) << (*i)->getName() << " "; prevChannelName = (*i)->getName(); } } LOG_USER(out) << std::endl << std::endl; } } // namespace logger