/***************************************************************************** * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2011 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef MAPNIK_DEBUG_HPP #define MAPNIK_DEBUG_HPP // mapnik (should not depend on anything that need to use this) #include #include #include // boost #include #ifdef MAPNIK_THREADSAFE #include #endif // std #include #include #include #include #include namespace mapnik { /* Global logger class that holds the configuration of severity, format and file/console redirection. */ class MAPNIK_DECL logger : public singleton, private mapnik::noncopyable { public: enum severity_type { debug = 0, warn = 1, error = 2, none = 3 }; typedef boost::unordered_map severity_map; // global security level static severity_type get_severity() { return severity_level_; } static void set_severity(const severity_type& severity_level) { #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(severity_mutex_); #endif severity_level_ = severity_level; } // per object security levels static severity_type get_object_severity(std::string const& object_name) { severity_map::iterator it = object_severity_level_.find(object_name); if (object_name.empty() || it == object_severity_level_.end()) { return severity_level_; } else { return it->second; } } static void set_object_severity(std::string const& object_name, const severity_type& security_level) { #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(severity_mutex_); #endif if (! object_name.empty()) { object_severity_level_[object_name] = security_level; } } static void clear_object_severity() { #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(severity_mutex_); #endif object_severity_level_.clear(); } // format static std::string get_format() { return format_; } static void set_format(std::string const& format) { #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(format_mutex_); #endif format_ = format; } // interpolate the format string for output static std::string str(); // output static void use_file(std::string const& filepath); static void use_console(); private: static severity_type severity_level_; static severity_map object_severity_level_; static bool severity_env_check_; static std::string format_; static bool format_env_check_; static std::ofstream file_output_; static std::string file_name_; static std::streambuf* saved_buf_; #ifdef MAPNIK_THREADSAFE static std::mutex severity_mutex_; static std::mutex format_mutex_; #endif }; namespace detail { /* Default sink, it regulates access to clog */ template class clog_sink { public: typedef std::basic_ostringstream stream_buffer; void operator()(const logger::severity_type& /*severity*/, const stream_buffer &s) { #ifdef MAPNIK_THREADSAFE static std::mutex mutex; mapnik::scoped_lock lock(mutex); #endif std::clog << logger::str() << " " << s.str() << std::endl; } }; /* Base log class, should not log anything when no MAPNIK_LOG is defined This is used for debug/warn reporting that should not output anything when not compiling for speed. */ template