// ball_scopedattribute.h -*-C++-*- #ifndef INCLUDED_BALL_SCOPEDATTRIBUTE #define INCLUDED_BALL_SCOPEDATTRIBUTE //@PURPOSE: Provide a scoped guard for a single BALL attribute. // //@CLASSES: // ball::ScopedAttribute: single attribute scoped guard // //@SEE_ALSO: ball_attribute // //@DESCRIPTION: This component defines a type, 'ball::ScopedAttribute', that // serves as a scoped guard for 'ball::Attribute' objects. It defines a single // attribute for the current thread while it is in scope. // // This component is used to associate an attribute (a name-value pair) with // the current thread context for use when writing log records for the current // thread. This context information can both be written to the log itself, and // used as input when evaluating whether a particular log should be written. // For more information on how to use this feature, please see the package // level documentation and usage examples for "Log Attributes" and "Rule-Based // Logging". // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic Usage of 'ball::ScopedAttribute' ///- - - - - - - - - - - - - - - - - - - - - - - - - // Suppose that service requests for a fictional service with id '999' are // handled asynchronously by the function below. Creating an instance of this // class will set BALL attributes for any logging performed while the request // is being processed: //.. // void handleServiceRequest(const Request& request) // { // BALL_LOG_SET_CATEGORY("MY.SERVICE"); // // ball::ScopedAttribute attribute("request", request.selectionName()); // // BALL_LOG_TRACE << "Handling request: " << request; // // // handle request here // } //.. // Attribute "request" will be set in the calling thread and will affect // publication of any BALL messages for the lifetime of 'attribute'. #include <balscm_version.h> #include <ball_attribute.h> #include <ball_attributecontainer.h> #include <ball_attributecontainerlist.h> #include <ball_attributecontext.h> #include <bslma_allocator.h> #include <bslma_stdallocator.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsls_keyword.h> #include <bsls_types.h> #include <bsls_assert.h> #include <bsl_iosfwd.h> #include <bsl_string.h> namespace BloombergLP { namespace ball { // =============================== // class ScopedAttribute_Container // =============================== class ScopedAttribute_Container : public AttributeContainer { // This component-private class is a concrete implementation of the // 'AttributeContainer' protocol for a single attribute. // DATA Attribute d_attribute; // NOT IMPLEMENTED ScopedAttribute_Container(const ScopedAttribute_Container&); ScopedAttribute_Container& operator=(const ScopedAttribute_Container&); public: // TYPES typedef bsl::allocator<char> allocator_type; // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(ScopedAttribute_Container, bslma::UsesBslmaAllocator); // CREATORS ScopedAttribute_Container( const char *name, const bsl::string_view& value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, const char *value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, int value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, long value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, long long value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, unsigned int value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, unsigned long value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, unsigned long long value, const allocator_type& allocator = allocator_type()); ScopedAttribute_Container( const char *name, const void *value, const allocator_type& allocator = allocator_type()); // Create a BALL attribute container holding a single rule, associating // the specified 'name' with the specified 'value'. Optionally specify // an 'allocator' (e.g., the address of a 'bslma::Allocator' object) to // supply memory; otherwise, the default allocator is used. virtual ~ScopedAttribute_Container(); // Destroy this object; // ACCESSORS bool hasValue(const Attribute& attribute) const BSLS_KEYWORD_OVERRIDE; // Return 'true' if the specified 'attribute' is the same as the value // held in this container, and 'false' otherwise. bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const BSLS_KEYWORD_OVERRIDE; // Format this object to the specified output 'stream' at the (absolute // value of) the optionally specified indentation 'level' and return a // reference to 'stream'. If 'level' is specified, optionally specify // 'spacesPerLevel', the number of spaces per indentation level for // this and all of its nested objects. If 'level' is negative, // suppress indentation of the first line. If 'spacesPerLevel' is // negative, format the entire output on one line, suppressing all but // the initial indentation (as governed by 'level'). If 'stream' is // not valid on entry, this operation has no effect. void visitAttributes(const bsl::function<void(const Attribute&)>& visitor) const BSLS_KEYWORD_OVERRIDE; // Invoke the specified 'visitor' function for all attributes in this // container. // Aspects allocator_type get_allocator() const; // Return the allocator used by this object to supply memory. Note // that if no allocator was supplied at construction the default // allocator in effect at construction is used. }; // ===================== // class ScopedAttribute // ===================== class ScopedAttribute { // This class provides a scoped guard that sets a single BALL attribute in // the current thread. // DATA ScopedAttribute_Container d_container; // contains the attribute const AttributeContext::iterator d_it; // reference to attribute // container // NOT IMPLEMENTED ScopedAttribute(const ScopedAttribute&); ScopedAttribute& operator=(const ScopedAttribute&); public: // TYPES typedef bsl::allocator<char> allocator_type; // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(ScopedAttribute, bslma::UsesBslmaAllocator); // CREATORS ScopedAttribute(const char *name, const bsl::string_view& value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, const char *value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, int value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, long value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, long long value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, unsigned int value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, unsigned long value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, unsigned long long value, const allocator_type& allocator = allocator_type()); ScopedAttribute(const char *name, const void *value, const allocator_type& allocator = allocator_type()); // Set BALL logging attributes for the current thread for the scope of // this object, associating the specified 'name' with the specified // 'value'. Optionally specify an 'allocator' (e.g., the address of a // 'bslma::Allocator' object) to supply memory; otherwise, the default // allocator is used. ~ScopedAttribute(); // Remove the attributes managed by this object from the BALL system, // and destroy this object. // Aspects allocator_type get_allocator() const; // Return the allocator used by this object to supply memory. Note // that if no allocator was supplied at construction the default // allocator in effect at construction is used. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------------- // class ScopedAttribute_Container // ------------------------------- // CREATORS inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, const bsl::string_view& value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, const char *value, const allocator_type& allocator) : d_attribute(name, static_cast<bsl::string>(value), allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, int value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, long value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, long long value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, unsigned int value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, unsigned long value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, unsigned long long value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } inline ScopedAttribute_Container::ScopedAttribute_Container( const char *name, const void *value, const allocator_type& allocator) : d_attribute(name, value, allocator) { } // ACCESSORS inline bool ScopedAttribute_Container::hasValue(const Attribute& attribute) const { return d_attribute == attribute; } inline void ScopedAttribute_Container::visitAttributes( const bsl::function<void(const ball::Attribute&)>& visitor) const { visitor(d_attribute); } // Aspects inline ScopedAttribute_Container::allocator_type ScopedAttribute_Container::get_allocator() const { return d_attribute.get_allocator(); } // --------------------- // class ScopedAttribute // --------------------- // CREATORS inline ScopedAttribute::ScopedAttribute(const char *name, const bsl::string_view& value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, const char *value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, int value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, long value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, long long value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, unsigned int value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, unsigned long value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, unsigned long long value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::ScopedAttribute(const char *name, const void *value, const allocator_type& allocator) : d_container(name, value, allocator) , d_it(AttributeContext::getContext()->addAttributes(&d_container)) { } inline ScopedAttribute::~ScopedAttribute() { AttributeContext::getContext()->removeAttributes(d_it); } // ACCESSORS // Aspects inline ScopedAttribute::allocator_type ScopedAttribute::get_allocator() const { return d_container.get_allocator(); } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------