### Writing your own attributes

    #include <boost/log/attributes/attribute.hpp>
    #include <boost/log/attributes/attribute_value.hpp>
    #include <boost/log/attributes/attribute_value_impl.hpp>

Developing your own attributes is quite simple. Generally, you need to do the following:

1. Define what will be the attribute value. Most likely, it will be a piece of constant data that you want to participate in filtering and formatting. Envelop this data into a class that derives from the `impl` interface; this is the attribute value implementation class. This object will have to implement the `dispatch` method that will extract the stored data (or, in other words, the stored value) to a type dispatcher. In most cases the class `attribute_value_impl` provided by the library can be used for this.
2. Use the `attribute_value` class as the interface class that holds a reference to the attribute value implementation.
3. Define how attribute values are going to be produced. In a corner case the values do not need to be produced (like in the case of the `constant` attribute provided by the library), but often there is some logic that needs to be invoked to acquire the attribute value. This logic has to be concentrated in a class derived from the `impl` interface, more precisely - in the `get_value` method. This class is the attribute implementation class. You can think of it as an attribute value factory.
4. Define the attribute interface class that derives from `attribute`. By convention, the interface class should create the corresponding implementation on construction and pass the pointer to it to the `attribute` class constructor. The interface class may have interface methods but it typically should not contain any data members as the data will be lost when the attribute is added to the library. All relevant data should be placed in the implementation class instead.

While designing an attribute, one has to strive to make it as independent from the values it produces, as possible. The attribute can be called from different threads concurrently to produce a value. Once produced, the attribute value can be used several times by the library (maybe even concurrently), it can outlive the attribute object that created it, and several attribute values produced by the same attribute can exist simultaneously.

From the library perspective, each attribute value is considered independent from other attribute values or the attribute itself. That said, it is still possible to implement attributes that are also attribute values, which allows to optimize performance in some cases. This is possible if the following requirements are fulfilled:

- The attribute value never changes, so it's possible to store it in the attribute itself. The `constant` attribute is an example.
- The attribute stores its value in a global (external with regard to the attribute) storage, that can be accessed from any attribute value. The attribute values must guarantee, though, that their stored values do not change over time and are safely accessible concurrently from different threads.

As a special case for the second point, it is possible to store attribute values (or their parts) in a thread-specific storage. However, in that case the user has to implement the `detach_from_thread` method of the attribute value implementation properly. The result of this method - another attribute value - must be independent from the thread it is being called in, but its stored value should be equivalent to the original attribute value. This method will be called by the library when the attribute value passes to a thread that is different from the thread where it was created. As of this moment, this will only happen in the case of asynchronous logging sinks.

But in the vast majority of cases attribute values must be self-contained objects with no dependencies on other entities. In fact, this case is so common that the library provides a ready to use attribute value implementation class template `attribute_value_impl` and `make_attribute_value` generator function. The class template has to be instantiated on the stored value type, and the stored value has to be provided to the class constructor. For example, let's implement an attribute that returns system uptime in seconds. This is the attribute implementation class.

    // The function returns the system uptime, in seconds
    unsigned int get_uptime();

    // Attribute implementation class
    class system_uptime_impl :
        public logging::attribute::impl
    {
    public:
        // The method generates a new attribute value
        logging::attribute_value get_value()
        {
            return attrs::make_attribute_value(get_uptime());
        }
    };

Since there is no need for special attribute value classes we can use the `make_attribute_value` function to create the value envelop.

| Tip
For cases like this, when the attribute value can be obtained in a single function call, it is typically more convenient to use the `function` attribute.

The interface class of the attribute can be defined as follows:

    // Attribute interface class
    class system_uptime :
        public logging::attribute
    {
    public:
        system_uptime() : logging::attribute(new system_uptime_impl())
        {
        }
        // Attribute casting support
        explicit system_uptime(attrs::cast_source const& source) : logging::attribute(source.as< system_uptime_impl >())
        {
        }
    };

As it was mentioned before, the default constructor creates the implementation instance so that the default constructed attribute can be used by the library.

The second constructor adds support for attribute casting. The constructor argument contains a reference to an attribute implementation object, and by calling `as` on it the constructor attempts to upcast it to the implementation object of our custom attribute. The `as` method will return `NULL` if the upcast fails, which will result in an empty attribute constructed in case of failure.

Having defined these two classes, the attribute can be used with the library as usual:

    void init_logging()
    {
        boost::shared_ptr< logging::core > core = logging::core::get();

        // ...

        // Add the uptime attribute to the core
        core->add_global_attribute("SystemUptime", system_uptime());
    }

See the complete code.