summaryrefslogtreecommitdiff
path: root/libs/log/example/settings_file_formatter_factory/main.cpp
blob: a925ae2794e3f9ba077d48aacdd46c8e955983e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 *          Copyright Andrey Semashev 2007 - 2014.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   main.cpp
 * \author Andrey Semashev
 * \date   12.05.2010
 *
 * \brief  An example of initializing the library from a settings file,
 *         with a custom formatter for an attribute.
 */

// #define BOOST_ALL_DYN_LINK 1

#include <string>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/log/core.hpp>
#include <boost/log/common.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/core/record.hpp>
#include <boost/log/attributes/value_visitation.hpp>
#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>

namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;

enum severity_level
{
    normal,
    notification,
    warning,
    error,
    critical
};

BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(test_lg, src::severity_logger< >)

//! Our custom formatter for the scope list
struct scope_list_formatter
{
    typedef void result_type;
    typedef attrs::named_scope::value_type scope_stack;

    explicit scope_list_formatter(logging::attribute_name const& name) :
        name_(name)
    {
    }
    void operator()(logging::record_view const& rec, logging::formatting_ostream& strm) const
    {
        // We need to acquire the attribute value from the log record
        logging::visit< scope_stack >
        (
            name_,
            rec.attribute_values(),
            boost::bind(&scope_list_formatter::format, _1, boost::ref(strm))
        );
    }

private:
    //! This is where our custom formatting takes place
    static void format(scope_stack const& scopes, logging::formatting_ostream& strm)
    {
        scope_stack::const_iterator it = scopes.begin(), end = scopes.end();
        for (; it != end; ++it)
        {
            strm << "\t" << it->scope_name << " [" << it->file_name << ":" << it->line << "]\n";
        }
    }

private:
    logging::attribute_name name_;
};

class my_scopes_formatter_factory :
    public logging::formatter_factory< char >
{
public:
    /*!
     * This function creates a formatter for the MyScopes attribute.
     * It effectively associates the attribute with the scope_list_formatter class
     */
    formatter_type create_formatter(
        logging::attribute_name const& attr_name, args_map const& args)
    {
        return formatter_type(scope_list_formatter(attr_name));
    }
};

//! The function initializes the logging library
void init_logging()
{
    // First thing - register the custom formatter for MyScopes
    logging::register_formatter_factory("MyScopes", boost::make_shared< my_scopes_formatter_factory >());

    // Then load the settings from the file
    std::ifstream settings("settings.txt");
    if (!settings.is_open())
        throw std::runtime_error("Could not open settings.txt file");
    logging::init_from_stream(settings);

    // Add some attributes
    logging::add_common_attributes();

    logging::core::get()->add_global_attribute("MyScopes", attrs::named_scope());
}

//! The function tests logging
void try_logging()
{
    BOOST_LOG_FUNCTION();

    src::severity_logger< >& lg = test_lg::get();

    BOOST_LOG_SEV(lg, critical) << "This is a critical severity record";

    BOOST_LOG_NAMED_SCOPE("random name");
    BOOST_LOG_SEV(lg, error) << "This is a error severity record";
}

int main(int argc, char* argv[])
{
    try
    {
        init_logging();
        try_logging();
    }
    catch (std::exception& e)
    {
        std::cout << "FAILURE: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}