예제 #1
0
파일: LoggerDB.cpp 프로젝트: Orvid/folly
std::vector<std::string> LoggerDB::processConfigString(
    folly::StringPiece config) {
  std::vector<std::string> errors;
  if (config.empty()) {
    return errors;
  }

  std::vector<StringPiece> pieces;
  folly::split(",", config, pieces);
  for (const auto& p : pieces) {
    auto idx = p.rfind('=');
    if (idx == folly::StringPiece::npos) {
      errors.emplace_back(
          folly::sformat("missing '=' in logger configuration: \"{}\"", p));
      continue;
    }

    auto category = p.subpiece(0, idx);
    auto level_str = p.subpiece(idx + 1);
    LogLevel level;
    try {
      level = stringToLogLevel(level_str);
    } catch (const std::exception&) {
      errors.emplace_back(folly::sformat(
          "invalid log level \"{}\" for category \"{}\"", level_str, category));
      continue;
    }

    setLevel(category, level);
  }

  return errors;
}
예제 #2
0
bool StringToLogLevel(const std::string& log_level_text, LogLevel& log_level)
{
  return stringToLogLevel(log_level_text, log_level);
}
예제 #3
0
void LoggingManager::initialize()
{
  if (!m_initialized)
  {
    m_initialized = true;

    // Read the log output stream configuration.
    ::icl_core::config::ConfigIterator output_stream_it =
        ::icl_core::config::find("\\/IclCore\\/Logging\\/(OutputStream.*)\\/(.*)");
    while (output_stream_it.next())
    {
      ::icl_core::String entry_name = output_stream_it.matchGroup(1);
      ::icl_core::String value_name = output_stream_it.matchGroup(2);
      if (value_name == "OutputStreamName")
      {
        m_output_stream_config[entry_name].output_stream_name = output_stream_it.value();
      }
      else if (value_name == "Name")
      {
        m_output_stream_config[entry_name].name = output_stream_it.value();
      }
      else if (value_name == "LogLevel")
      {
        if (!stringToLogLevel(output_stream_it.value(), m_output_stream_config[entry_name].log_level))
        {
          std::cerr << "LOGGING CONFIG ERROR: Illegal log level in " << output_stream_it.key() << std::endl;
        }
      }
      else if (value_name.substr(0, 9) == "LogStream")
      {
        m_output_stream_config[entry_name].log_streams.push_back(output_stream_it.value());
      }
    }

    // Read the log stream configuration.
    ::icl_core::config::ConfigIterator log_stream_it =
        ::icl_core::config::find("\\/IclCore\\/Logging\\/(LogStream.*)\\/(.*)");
    while (log_stream_it.next())
    {
      ::icl_core::String entry_name = log_stream_it.matchGroup(1);
      ::icl_core::String value_name = log_stream_it.matchGroup(2);
      if (value_name == "Name")
      {
        m_log_stream_config[entry_name].name = log_stream_it.value();
      }
      else if (value_name == "LogLevel")
      {
        if (!stringToLogLevel(log_stream_it.value(), m_log_stream_config[entry_name].log_level))
        {
          std::cerr << "LOGGING CONFIG ERROR: Illegal log level in " << log_stream_it.key() << std::endl;
        }
      }
    }
  }

  configure();

  // Configure the "QuickDebug" log stream and log output stream.
  icl_core::String quick_debug_filename;
  if (icl_core::config::paramOpt<icl_core::String>("quick-debug", quick_debug_filename))
  {
    // Find an unused name for the QuickDebug[0-9]* log output stream.
    icl_core::String output_stream_name = "QuickDebug";
    LogOutputStreamMap::const_iterator find_it = m_log_output_streams.find(output_stream_name);
    if (find_it != m_log_output_streams.end())
    {
      size_t count = 0;
      do
      {
        ++count;
        find_it = m_log_output_streams.find(output_stream_name
                                            + boost::lexical_cast<icl_core::String>(count));
      }
      while (find_it != m_log_output_streams.end());
      output_stream_name = output_stream_name + boost::lexical_cast<icl_core::String>(count);
    }

    // Create the log output stream and connect the log stream.
    LogOutputStream *output_stream = new FileLogOutput(output_stream_name, quick_debug_filename,
                                                       eLL_TRACE, true);
    m_log_output_streams[output_stream_name] = output_stream;
    QuickDebug::instance().addOutputStream(output_stream);
    QuickDebug::instance().m_initial_level = eLL_TRACE;
  }

  // Run the log output stream threads.
  if (m_default_log_output != 0)
  {
    m_default_log_output->start();
  }
  for (LogOutputStreamMap::iterator output_stream_it = m_log_output_streams.begin();
       output_stream_it != m_log_output_streams.end();
       ++output_stream_it)
  {
    output_stream_it->second->start();
  }
}
예제 #4
0
void LoggingManager::configure()
{
  // Create the default log output stream, if necessary.
  if (m_output_stream_config.empty() && m_default_log_output == NULL)
  {
    m_default_log_output = StdLogOutput::create("Default", "/IclCore/Logging/Default");
  }

  // Create log stream instances, if necessary.
  for (LogStreamFactoryMap::iterator log_stream_it = m_log_stream_factories.begin();
       log_stream_it != m_log_stream_factories.end(); ++log_stream_it)
  {
    if (m_log_streams.find(log_stream_it->first) == m_log_streams.end())
    {
      registerLogStream((*log_stream_it->second)());
    }
  }

  // Delete the default log output stream, if necessary.
  if (!m_output_stream_config.empty() && m_default_log_output != NULL)
  {
    for (LogStreamMap::iterator it = m_log_streams.begin(); it != m_log_streams.end(); ++it)
    {
      it->second->removeOutputStream(m_default_log_output);
    }

    m_default_log_output->shutdown();
    delete m_default_log_output;
    m_default_log_output = 0;
  }

  // Run through the log output stream configuration
  for (LogOutputStreamConfigMap::iterator loc_it = m_output_stream_config.begin();
       loc_it != m_output_stream_config.end(); ++loc_it)
  {
    // Auto-generate a suitable name for the log output stream, if it
    // has not been set in the configuration.
    if (loc_it->second.name == ::icl_core::String())
    {
      loc_it->second.name = loc_it->second.output_stream_name;
    }

    // Create the configured log output stream, if necessary.
    LogOutputStreamMap::const_iterator find_log_output_stream =
      m_log_output_streams.find(loc_it->second.name);
    if (find_log_output_stream == m_log_output_streams.end())
    {
      LogOutputStreamFactoryMap::const_iterator find_log_output_stream_factory =
        m_log_output_stream_factories.find(loc_it->second.output_stream_name);
      if (find_log_output_stream_factory == m_log_output_stream_factories.end())
      {
        // If the log output stream cannot be created then skip to the
        // next configuration entry.
        continue;
      }
      LogOutputStream *log_output_stream =
        (*find_log_output_stream_factory->second)(loc_it->second.name,
                                                  "/IclCore/Logging/" + loc_it->first,
                                                  loc_it->second.log_level);
      boost::tuples::tie(find_log_output_stream, boost::tuples::ignore) =
        m_log_output_streams.insert(std::make_pair(loc_it->second.name, log_output_stream));
    }

    // Check again, just to be sure!
    if (find_log_output_stream != m_log_output_streams.end())
    {
      // Connect the configured log streams (either the list from the
      // commandline or all available log streams).
      if (loc_it->second.log_streams.empty())
      {
        for (LogStreamMap::iterator it = m_log_streams.begin(); it != m_log_streams.end(); ++it)
        {
          it->second->addOutputStream(find_log_output_stream->second);
        }
      }
      else
      {
        for (StringList::const_iterator it = loc_it->second.log_streams.begin();
             it != loc_it->second.log_streams.end(); ++it)
        {
          LogStreamMap::iterator find_it = m_log_streams.find(*it);
          if (find_it == m_log_streams.end())
          {
            // If the log stream cannot be found then skip to the next
            // entry.  Maybe there will be a second call to configure()
            // in the future and the log stream is available then.
            continue;
          }
          else
          {
            find_it->second->addOutputStream(find_log_output_stream->second);
          }
        }
      }
    }
  }

  // Set the log level of the configured log streams (either the list
  // from the commandline or all available log streams).
  for (LogStreamConfigMap::const_iterator lsc_it = m_log_stream_config.begin();
       lsc_it != m_log_stream_config.end(); ++lsc_it)
  {
    LogStreamMap::iterator find_it = m_log_streams.find(lsc_it->second.name);
    if (find_it == m_log_streams.end())
    {
      // If the log stream cannot be found then skip to the next
      // entry.  Maybe there will be a second call to configure() in
      // the future and the log stream is available then.
      continue;
    }
    else
    {
      find_it->second->m_initial_level = lsc_it->second.log_level;
    }
  }


  if (icl_core::config::Getopt::instance().paramOptPresent("log-level"))
  {
    LogLevel initial_level = cDEFAULT_LOG_LEVEL;
    icl_core::String log_level = icl_core::config::Getopt::instance().paramOpt("log-level");
    if (!stringToLogLevel(log_level, initial_level))
    {
      std::cerr << "Illegal log level " << log_level << std::endl;
      std::cerr << "Valid levels are 'Trace', 'Debug', 'Info', 'Warning', 'Error' and 'Mute'." << std::endl;
    }
    else
    {
      if (m_default_log_output == NULL)
      {
        m_default_log_output = StdLogOutput::create("Default", "/IclCore/Logging/Default");
      }
      m_default_log_output->setLogLevel(initial_level);

      for (LogStreamMap::iterator lsm_it = m_log_streams.begin(); lsm_it != m_log_streams.end(); ++lsm_it)
      {
        lsm_it->second->m_initial_level = initial_level;
        lsm_it->second->addOutputStream(m_default_log_output);
      }

      for (LogOutputStreamMap::iterator los_it = m_log_output_streams.begin(); los_it
             != m_log_output_streams.end(); ++los_it)
      {
        los_it->second->setLogLevel(initial_level);
      }
    }
  }
}
예제 #5
0
std::shared_ptr<StandardLogHandler> StandardLogHandlerFactory::createHandler(
    StringPiece type,
    WriterFactory* writerFactory,
    const Options& options) {
  std::unique_ptr<FormatterFactory> formatterFactory;

  // Get the log formatter type
  auto* formatterType = get_ptr(options, "formatter");
  if (!formatterType || *formatterType == "glog") {
    formatterFactory = std::make_unique<GlogFormatterFactory>();
  } else if (!formatterType || *formatterType == "custom") {
    formatterFactory = std::make_unique<CustomLogFormatterFactory>();
  } else {
    throw std::invalid_argument(
        to<string>("unknown log formatter type \"", *formatterType, "\""));
  }

  Optional<LogLevel> syncLevel;

  // Process the log formatter and log handler options
  std::vector<string> errors;
  for (const auto& entry : options) {
    bool handled = false;
    try {
      // Allow both the formatterFactory and writerFactory to consume an
      // option.  In general they probably should have mutually exclusive
      // option names, but we don't give precedence to one over the other here.
      handled |= formatterFactory->processOption(entry.first, entry.second);
      handled |= writerFactory->processOption(entry.first, entry.second);
    } catch (const std::exception& ex) {
      errors.push_back(to<string>(
          "error processing option \"", entry.first, "\": ", ex.what()));
      continue;
    }

    // We explicitly processed the "formatter" option above.
    handled |= handled || (entry.first == "formatter");

    // Process the "sync_level" option.
    if (entry.first == "sync_level") {
      try {
        syncLevel = stringToLogLevel(entry.second);
      } catch (const std::exception& ex) {
        errors.push_back(to<string>(
            "unable to parse value for option \"",
            entry.first,
            "\": ",
            ex.what()));
      }
      handled = true;
    }

    // Complain about unknown options.
    if (!handled) {
      errors.push_back(to<string>("unknown option \"", entry.first, "\""));
    }
  }

  if (!errors.empty()) {
    throw std::invalid_argument(join(", ", errors));
  }

  // Construct the formatter and writer
  auto writer = writerFactory->createWriter();
  auto formatter = formatterFactory->createFormatter(writer);

  if (syncLevel) {
    return std::make_shared<StandardLogHandler>(
        LogHandlerConfig{type, options}, formatter, writer, *syncLevel);
  } else {
    return std::make_shared<StandardLogHandler>(
        LogHandlerConfig{type, options}, formatter, writer);
  }
}