From a902a08aabbe9c52c7cb0415496b55c0f37fc1c3 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Tue, 10 Apr 2012 00:25:31 +0200 Subject: [PATCH] - added logging to file - started working on the logger bindings - cleanups some error reporting with cerr/clog in the library --- bindings/python/mapnik_logger.cpp | 116 +++++++++++++++++++----- include/mapnik/debug.hpp | 84 +++++++++-------- include/mapnik/font_engine_freetype.hpp | 11 ++- include/mapnik/json/feature_grammar.hpp | 12 +-- include/mapnik/utils.hpp | 9 +- plugins/input/geos/geos_datasource.cpp | 30 +++--- src/agg/process_markers_symbolizer.cpp | 6 +- src/debug.cpp | 61 ++++++++++++- src/libxml2_loader.cpp | 2 +- 9 files changed, 227 insertions(+), 104 deletions(-) diff --git a/bindings/python/mapnik_logger.cpp b/bindings/python/mapnik_logger.cpp index 403960fc7..b6c0aeba9 100644 --- a/bindings/python/mapnik_logger.cpp +++ b/bindings/python/mapnik_logger.cpp @@ -23,43 +23,111 @@ #include #include +using mapnik::logger::severity; +using mapnik::logger::format; +using mapnik::logger::output; + +void set_severity(const severity::type& s) +{ + severity::set(s); +} + +severity::type get_severity() +{ + return severity::get(); +} + +void set_object_severity(const std::string& object_name, const severity::type& s) +{ + severity::set_object(object_name, s); +} + +severity::type get_object_severity(const std::string& object_name) +{ + return severity::get_object(object_name); +} + + void export_logger() { - // TODO - expose the logger global class - - /* using namespace boost::python; - enum_("severity") - .value("Info", mapnik::logger::severity::info) - .value("Debug", mapnik::logger::severity::debug) - .value("Warn", mapnik::logger::severity::warn) - .value("Error", mapnik::logger::severity::error) - .value("Fatal", mapnik::logger::severity::fatal) - .value("None", mapnik::logger::severity::none) + enum_("SeverityType") + .value("Info", severity::info) + .value("Debug", severity::debug) + .value("Warn", severity::warn) + .value("Error", severity::error) + .value("Fatal", severity::fatal) + .value("None", severity::none) ; - */ - /* - using mapnik::freetype_engine; +/* using mapnik::singleton; using mapnik::CreateStatic; using namespace boost::python; - class_,boost::noncopyable>("Singleton",no_init) - .def("instance",&singleton::instance, + + class_,boost::noncopyable>("Singleton",no_init) + .def("instance",&singleton::instance, return_value_policy()) .staticmethod("instance") ; - class_ >, - boost::noncopyable>("FontEngine",no_init) - .def("register_font",&freetype_engine::register_font) - .def("register_fonts",&freetype_engine::register_fonts) - .def("face_names",&freetype_engine::face_names) - .staticmethod("register_font") - .staticmethod("register_fonts") - .staticmethod("face_names") + class_ >, + boost::noncopyable>("Severity",no_init) + .def("get",&severity::get) + .def("set",&severity::set) + .def("get_object",&severity::get_object) + .def("set_object",&severity::set_object) + .staticmethod("get") + .staticmethod("set") + .staticmethod("get_object") + .staticmethod("set_object") ; +*/ + + def("set_severity", &set_severity, + "\n" + "Set global logger severity.\n" + "\n" + "Usage:\n" + ">>> from mapnik import SeverityType, set_severity\n" + ">>> set_severity(SeverityType.None)\n" + ">>> set_severity(SeverityType.Info)\n" + ">>> set_severity(SeverityType.Debug)\n" + ">>> set_severity(SeverityType.Warn)\n" + ">>> set_severity(SeverityType.Error)\n" + ">>> set_severity(SeverityType.Fatal)\n" + ); + + def("get_severity", &get_severity, + "\n" + "Get global logger severity.\n" + "\n" + "Usage:\n" + ">>> from mapnik import get_severity\n" + ">>> get_severity()\n" + ); + + def("set_object_severity", &set_object_severity, + "\n" + "Set logger severity for a single object.\n" + "\n" + "Usage:\n" + ">>> from mapnik import SeverityType, set_object_severity\n" + ">>> set_object_severity('ogr', SeverityType.None)\n" + ">>> set_object_severity('gdal', SeverityType.Info)\n" + ">>> set_object_severity('cairo_renderer', SeverityType.Debug)\n" + ">>> set_object_severity('agg_renderer', SeverityType.Warn)\n" + ">>> set_object_severity('bindings', SeverityType.Error)\n" + ); + + def("get_object_severity", &get_object_severity, + "\n" + "Get logger severity for a single object.\n" + "\n" + "Usage:\n" + ">>> from mapnik import get_object_severity" + ">>> get_object_severity('ogr')\n" + ); - */ } diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp index 396b89134..93ff737d0 100644 --- a/include/mapnik/debug.hpp +++ b/include/mapnik/debug.hpp @@ -23,8 +23,9 @@ #ifndef MAPNIK_DEBUG_HPP #define MAPNIK_DEBUG_HPP -// mapnik (should not depend on anything else) +// mapnik (should not depend on anything that need to use this) #include +#include // boost #include @@ -35,7 +36,6 @@ // std #include -#include #include #include #include @@ -45,7 +45,9 @@ namespace mapnik { namespace logger { - class severity + class MAPNIK_DECL severity : + public singleton, + private boost::noncopyable { public: enum type @@ -113,7 +115,9 @@ namespace mapnik { }; - class format + class MAPNIK_DECL format : + public singleton, + private boost::noncopyable { public: @@ -141,8 +145,23 @@ namespace mapnik { }; + class MAPNIK_DECL output : + public singleton, + private boost::noncopyable + { + public: + static void use_file(const std::string& filepath); + static void use_console(); + + private: + static std::ofstream file_output_; + static std::string file_name_; + static std::streambuf* saved_buf_; + }; + + template - class output_to_clog + class clog_sink { public: typedef std::basic_ostringstream stream_buffer; @@ -210,55 +229,43 @@ namespace mapnik { std::string object_name_; #endif }; + + typedef base_log base_log_info; + typedef base_log base_log_debug; + typedef base_log base_log_warn; + typedef base_log base_log_error; + typedef base_log base_log_fatal; } - class MAPNIK_DECL log : public logger::base_log { + class MAPNIK_DECL info : public logger::base_log_info { public: - typedef logger::base_log base_class; - log(const char* object_name) : base_class(object_name) {} - log() : base_class() {} + info() : logger::base_log_info() {} + info(const char* object_name) : logger::base_log_info(object_name) {} }; - class MAPNIK_DECL info : public logger::base_log { + class MAPNIK_DECL debug : public logger::base_log_debug { public: - typedef logger::base_log base_class; - info(const char* object_name) : base_class(object_name) {} - info() : base_class() {} + debug() : logger::base_log_debug() {} + debug(const char* object_name) : logger::base_log_debug(object_name) {} }; - class MAPNIK_DECL debug : public logger::base_log { + class MAPNIK_DECL warn : public logger::base_log_warn { public: - typedef logger::base_log base_class; - debug(const char* object_name) : base_class(object_name) {} - debug() : base_class() {} + warn() : logger::base_log_warn() {} + warn(const char* object_name) : logger::base_log_warn(object_name) {} }; - class MAPNIK_DECL warn : public logger::base_log { + class MAPNIK_DECL error : public logger::base_log_error { public: - typedef logger::base_log base_class; - warn(const char* object_name) : base_class(object_name) {} - warn() : base_class() {} + error() : logger::base_log_error() {} + error(const char* object_name) : logger::base_log_error(object_name) {} }; - class MAPNIK_DECL error : public logger::base_log { + class MAPNIK_DECL fatal : public logger::base_log_fatal { public: - typedef logger::base_log base_class; - error(const char* object_name) : base_class(object_name) {} - error() : base_class() {} - }; - - class MAPNIK_DECL fatal : public logger::base_log { - public: - typedef logger::base_log base_class; - fatal(const char* object_name) : base_class(object_name) {} - fatal() : base_class() {} + fatal() : logger::base_log_fatal() {} + fatal(const char* object_name) : logger::base_log_fatal(object_name) {} }; @@ -267,7 +274,6 @@ namespace mapnik { #define MAPNIK_LOG_WARN(s) mapnik::warn(#s) #define MAPNIK_LOG_ERROR(s) mapnik::error(#s) #define MAPNIK_LOG_FATAL(s) mapnik::fatal(#s) - } #endif // MAPNIK_DEBUG_HPP diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index cf717c475..8018a7371 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -306,11 +306,12 @@ public: if (face_ptr face = get_face(*name)) { face_set->add(face); - } else { -#ifdef MAPNIK_DEBUG - // TODO - handle with mapnik::log - std::cerr << "Failed to find face '" << *name << "' in font set '" << fset.get_name() << "'\n"; -#endif + } + else + { + MAPNIK_LOG_ERROR(font_engine_freetype) + << "Failed to find face '" << *name + << "' in font set '" << fset.get_name() << "'\n"; } } return face_set; diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp index 9f37959c8..d45971817 100644 --- a/include/mapnik/json/feature_grammar.hpp +++ b/include/mapnik/json/feature_grammar.hpp @@ -266,12 +266,12 @@ struct feature_grammar : // ; - coordinates = eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)) - | eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)) - | eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)) - | eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1)) - | eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)) - | eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)) + coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1))) ; point_coordinates = eps[ _a = new_(Point) ] diff --git a/include/mapnik/utils.hpp b/include/mapnik/utils.hpp index dfa1bc959..284a2c190 100644 --- a/include/mapnik/utils.hpp +++ b/include/mapnik/utils.hpp @@ -28,9 +28,6 @@ #include #endif -// mapnik -#include - // stl #include #include @@ -123,9 +120,7 @@ template ::destroy(pInstance_); pInstance_ = 0; - destroyed_=true; - - MAPNIK_LOG_DEBUG(utils) << "singleton: Destroyed instance"; + destroyed_ = true; } protected: @@ -151,8 +146,6 @@ public: { pInstance_ = CreatePolicy::create(); - MAPNIK_LOG_DEBUG(utils) << "singleton: Created instance"; - // register destruction std::atexit(&DestroySingleton); } diff --git a/plugins/input/geos/geos_datasource.cpp b/plugins/input/geos/geos_datasource.cpp index 8b830a2cc..e10604e3a 100644 --- a/plugins/input/geos/geos_datasource.cpp +++ b/plugins/input/geos/geos_datasource.cpp @@ -63,30 +63,26 @@ using mapnik::filter_at_point; DATASOURCE_PLUGIN(geos_datasource) -void geos_notice(const char* fmt, ...) +void geos_notice(const char* format, ...) { - // TODO - handle with mapnik::log + char buffer[512]; - va_list ap; - fprintf( stdout, "Mapnik LOG> geos_datasource: (GEOS NOTICE) "); + va_list args; + va_start(args, fmt); + vsprintf(buffer, format, args); + va_end(args); - va_start (ap, fmt); - vfprintf( stdout, fmt, ap); - va_end(ap); - fprintf( stdout, "\n" ); + MAPNIK_LOG_WARN(geos) << "geos_datasource: " << buffer; } -void geos_error(const char* fmt, ...) +void geos_error(const char* format, ...) { - // TODO - handle with mapnik::log + va_list args; + va_start(args, fmt); + vsprintf(buffer, format, args); + va_end(args); - va_list ap; - fprintf( stdout, "Mapnik LOG> geos_datasource: (GEOS ERROR) "); - - va_start (ap, fmt); - vfprintf( stdout, fmt, ap); - va_end(ap); - fprintf( stdout, "\n" ); + MAPNIK_LOG_ERROR(geos) << "geos_datasource: " << buffer; } diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 96f37f5d4..8ab15d69e 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -196,7 +196,8 @@ void agg_renderer::process(markers_symbolizer const& sym, tr.transform(&x1,&y1); tr.transform(&x2,&y2); extent.init(x1,y1,x2,y2); - //mapnik::log() << "agg_renderer: " << x1 << " " << y1 << " " << x2 << " " << y2 << "\n"; + + //MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: " << x1 << " " << y1 << " " << x2 << " " << y2 << "\n"; } else { @@ -207,7 +208,8 @@ void agg_renderer::process(markers_symbolizer const& sym, tr.transform(&x1,&y1); tr.transform(&x2,&y2); extent.init(x1,y1,x2,y2); - //mapnik::log() << "agg_renderer: " << x1 << " " << y1 << " " << x2 << " " << y2 << "\n"; + + //MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: " << x1 << " " << y1 << " " << x2 << " " << y2 << "\n"; } diff --git a/src/debug.cpp b/src/debug.cpp index a0d0290c3..5e2872585 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -32,6 +32,7 @@ namespace mapnik { namespace logger { + // severity severity::type severity::severity_level_ = @@ -44,17 +45,23 @@ severity::type severity::severity_level_ = severity::severity_map severity::object_severity_level_ = severity::severity_map(); +#ifdef MAPNIK_THREADSAFE +boost::mutex severity::mutex_; +#endif + // format #define __xstr__(s) __str__(s) #define __str__(s) #s - std::string format::format_ = __xstr__(MAPNIK_LOG_FORMAT); - #undef __xstr__ #undef __str__ +#ifdef MAPNIK_THREADSAFE +boost::mutex format::mutex_; +#endif + std::string format::str() { char buf[256]; @@ -64,5 +71,55 @@ std::string format::str() } +// output + +std::ofstream output::file_output_; +std::string output::file_name_; +std::streambuf* output::saved_buf_ = 0; + +void output::use_file(const std::string& filepath) +{ + // save clog rdbuf + if (saved_buf_ == 0) + { + saved_buf_ = std::clog.rdbuf(); + } + + // use a file to output as clog rdbuf + if (file_name_ != filepath) + { + file_name_ = filepath; + + if (file_output_.is_open()) + { + file_output_.close(); + } + + file_output_.open(file_name_.c_str(), std::ios::out | std::ios::app); + if (file_output_) + { + std::clog.rdbuf(file_output_.rdbuf()); + } + else + { + std::stringstream s; + s << "cannot redirect log to file " << file_output_; + throw std::runtime_error(s.str()); + } + } +} + +void output::use_console() +{ + // save clog rdbuf + if (saved_buf_ == 0) + { + saved_buf_ = std::clog.rdbuf(); + } + + std::clog.rdbuf(saved_buf_); +} + + } } diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index d9ea5a111..278d46706 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -100,7 +100,7 @@ public: /* if ( ! ctx->valid ) { - mapnik::log() << "libxml2_loader: Failed to validate DTD."; + MAPNIK_LOG_WARN(libxml2_loader) << "libxml2_loader: Failed to validate DTD."; } */ load(doc, node);