示例#1
0
int logger_impl::format_message(
    char* buf, size_t size, bool add_new_line,
    bool a_show_ident, bool a_show_location,
    const timestamp& a_tv,
    const log_msg_info& info, const char* fmt, va_list args
) throw (badarg_error)
{
    int len = a_tv.write(m_log_mgr->timestamp_type(), buf, size);
    const char* end = buf + size - 2;
    const char* q   = logger::log_level_to_str(info.level());
    char* p = buf + len;
    *p++ = '|';
    const char* e = p + 7;
    while (*q)    *p++ = *q++;
    while (p < e) *p++ = ' ';
    *p++ = '|';
    if (a_show_ident) {
        q = info.get_logger().ident().c_str();
        while (*q) *p++ = *q++;
        *p++ = '|';
    }
    int n = vsnprintf(p, end - p, fmt, args);

    if (n < 0)
        throw badarg_error("Error formatting string:", fmt, ' ',
            (info.has_src_location() ? info.src_location() : ""));
    p += n;

    if (info.has_src_location() && a_show_location) {
        q = info.src_location();
        while (*q && p != end) *p++ = *q++;
        if (add_new_line) *p++ = '\n';
    } else if (add_new_line)
        *p++ = '\n';
    *p = '\0';
    len = p - buf;
    BOOST_ASSERT(len <= (int)size);
    return len;
}
示例#2
0
文件: logger.cpp 项目: saleyn/utxx
void logger::init(const config_tree& a_cfg, const sigset_t* a_ignore_signals,
                  bool a_install_finalizer)
{
    if (m_initialized)
        throw std::runtime_error("Logger already initialized!");

    std::lock_guard<std::mutex> guard(m_mutex);
    do_finalize();

    try {
        m_show_location  = a_cfg.get<bool>       ("logger.show-location",    m_show_location);
        m_show_fun_namespaces = a_cfg.get<int>   ("logger.show-fun-namespaces",
                                m_show_fun_namespaces);
        m_show_category  = a_cfg.get<bool>       ("logger.show-category",    m_show_category);
        m_show_ident     = a_cfg.get<bool>       ("logger.show-ident",       m_show_ident);
        m_show_thread    = a_cfg.get<bool>       ("logger.show-thread",      m_show_thread);
        m_fatal_kill_signal = a_cfg.get<int>     ("logger.fatal-kill-signal",m_fatal_kill_signal);
        m_ident          = a_cfg.get<std::string>("logger.ident",            m_ident);
        m_ident          = replace_macros(m_ident);
        std::string ts   = a_cfg.get<std::string>("logger.timestamp",     "time-usec");
        m_timestamp_type = parse_stamp_type(ts);
        std::string levs = a_cfg.get<std::string>("logger.levels", "");
        if (!levs.empty())
            set_level_filter(static_cast<log_level>(parse_log_levels(levs)));
        std::string ls   = a_cfg.get<std::string>("logger.min-level-filter", "info");
        if (!levs.empty() && !ls.empty())
            std::runtime_error
            ("Either 'levels' or 'min-level-filter' option is permitted!");
        set_min_level_filter(parse_log_level(ls));
        long timeout_ms  = a_cfg.get<int>        ("logger.wait-timeout-ms", 1000);
        m_wait_timeout   = timespec{timeout_ms / 1000, timeout_ms % 1000 *  1000000L};
        m_sched_yield_us = a_cfg.get<long>       ("logger.sched-yield-us",  -1);
        m_silent_finish  = a_cfg.get<bool>       ("logger.silent-finish",   false);
        m_block_signals  = a_cfg.get<bool>       ("logger.block-signals",   true);

        if ((int)m_timestamp_type < 0)
            throw std::runtime_error("Invalid timestamp type: " + ts);

        // Install crash signal handlers
        // (SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM)
        if (a_cfg.get("logger.handle-crash-signals", true)) {
            sigset_t sset = sig_members_parse
                            (a_cfg.get("logger.handle-crash-signals.signals",""), UTXX_SRC);

            // Remove signals from the sset that are handled externally
            if (a_ignore_signals)
                for (uint i=1; i < sig_names_count(); ++i)
                    if (sigismember(a_ignore_signals, i))
                        sigdelset(&sset, i);

            if (install_sighandler(true, &sset)) {
                auto old = m_crash_sigset.exchange(new sigset_t(sset));
                if (!old)
                    delete old;
            }
        }

        //logger_impl::msg_info info(NULL, 0);
        //query_timestamp(info);

        logger_impl_mgr& lim = logger_impl_mgr::instance();

        std::lock_guard<std::mutex> guard(lim.mutex());

        // Check the list of registered implementations. If corresponding
        // configuration section is found, initialize the implementation.
        for(logger_impl_mgr::impl_map_t::iterator it=lim.implementations().begin();
                it != lim.implementations().end();
                ++it)
        {
            std::string path = std::string("logger.") + it->first;
            if (a_cfg.get_child_optional(path)) {
                // Determine if implementation of this type is already
                // registered with the logger
                bool found = false;
                for(implementations_vector::iterator
                        im = m_implementations.begin(), iend = m_implementations.end();
                        im != iend; ++im)
                    if (it->first == (*im)->name()) {
                        found = true;
                        break;
                    }

                if (found)
                    throw badarg_error("Implementation '", it->first,
                                       "' is already registered with the logger!");

                // A call to it->second() creates a logger_impl* pointer.
                // We need to call implementation's init function that may throw,
                // so use RAII to guarantee proper cleanup.
                logger_impl_mgr::impl_callback_t& f = it->second;
                m_implementations.emplace_back( f(it->first.c_str()) );
                auto& i = m_implementations.back();
                i->set_log_mgr(this);
                i->init(a_cfg);
            }
        }

        m_initialized = true;
        m_abort       = false;

        m_thread.reset(new std::thread([this]() {
            this->run();
        }));

        if (!m_finalizer_installed && a_install_finalizer) {
            atexit(&finalize_logger_at_exit);
            m_finalizer_installed = true;
        }
    } catch (std::runtime_error& e) {
        if (m_error)
            m_error(e.what());
        else
            throw;
    }
}