00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef IH_SENF_Utils_Logger_Target_
00027 #define IH_SENF_Utils_Logger_Target_ 1
00028
00029
00030 #include <set>
00031 #include <memory>
00032 #include <boost/type_traits/is_same.hpp>
00033 #include <boost/static_assert.hpp>
00034 #include <boost/shared_ptr.hpp>
00035 #include <senf/Utils/singleton.hh>
00036 #include <senf/Utils/mpl.hh>
00037 #include <senf/Utils/Console/LazyDirectory.hh>
00038 #include <senf/Utils/Console/Parse.hh>
00039
00040
00041
00042 namespace senf {
00043
00044 namespace console { class DirectoryNode; }
00045
00046 namespace log {
00047 namespace detail {
00048
00049 struct LogParameters {
00050 StreamBase const * stream;
00051 AreaBase const * area;
00052 unsigned level;
00053 void clear();
00054 void setDefaults();
00055 static LogParameters defaultParameters();
00056 };
00057
00058 std::ostream & operator<<(std::ostream & os, LogParameters const & pm);
00059
00060 void senf_console_parse_argument(console::ParseCommandInfo::TokensRange const & tokens,
00061 LogParameters & out);
00062
00064 class TargetRegistry
00065 : public senf::singleton<TargetRegistry>
00066 {
00067 public:
00068 enum Level {
00069 VERBOSE = senf::log::VERBOSE::value,
00070 NOTICE = senf::log::NOTICE::value,
00071 MESSAGE = senf::log::MESSAGE::value,
00072 IMPORTANT = senf::log::IMPORTANT::value,
00073 CRITICAL = senf::log::CRITICAL::value,
00074 FATAL = senf::log::FATAL::value
00075 };
00076
00077 using senf::singleton<TargetRegistry>::instance;
00078
00079 void write(StreamBase const & stream, AreaBase const & area, unsigned level,
00080 std::string const & msg);
00081
00082 void routed();
00083 bool fallbackRouting();
00084
00085 senf::console::ScopedDirectory<> & consoleDir();
00086
00087 void dynamicTarget(std::auto_ptr<Target> target);
00088
00089 private:
00090 TargetRegistry();
00091 ~TargetRegistry();
00092
00093 void registerTarget(Target * target, std::string const & name);
00094 void unregisterTarget(Target * target);
00095
00096 void consoleAreas(std::ostream & os);
00097 void consoleStreams(std::ostream & os);
00098 void consoleWrite(LogParameters parameters, std::string const & msg);
00099 void consoleRemoveTarget(Target * target);
00100 boost::shared_ptr<senf::console::DirectoryNode> consoleSelf(std::ostream & os);
00101
00102 typedef std::set<Target *> Targets;
00103 Targets targets_;
00104
00105 bool fallbackRouting_;
00106
00107 console::LazyDirectory consoleDir_;
00108
00109 Targets dynamicTargets_;
00110
00111 friend class senf::log::Target;
00112 friend class senf::singleton<TargetRegistry>;
00113 };
00114
00116 template <class Stream, class Area, class Level>
00117 void write(std::string const & msg);
00118
00119 #ifndef DOXYGEN
00120
00121
00122
00123
00124 senf::mpl::rv<0u> RouteParameterCheck_(...);
00125 senf::mpl::rv<1u> RouteParameterCheck_(StreamBase *);
00126 senf::mpl::rv<2u> RouteParameterCheck_(AreaBase *);
00127 template <class T> senf::mpl::rv<3u> RouteParameterCheck_(T*, typename T::SENFLogArea * = 0);
00128 senf::mpl::rv<4u> RouteParameterCheck_(LevelBase *);
00129
00130
00131
00132 template < class T, class A2, class A1,
00133 unsigned type = SENF_MPL_RV( senf::log::detail::RouteParameterCheck_(static_cast<T*>(0)) ) >
00134 struct RouteParameters
00135 {};
00136
00137 template <class A2, class A1>
00138 struct RouteParameters<mpl::nil,A2,A1,0u>
00139 : public RouteParameters<A2,A1,mpl::nil>
00140 {};
00141
00142 struct NilLevel {
00143 static unsigned const value = NONE::value;
00144 };
00145
00146 template <>
00147 struct RouteParameters<mpl::nil,mpl::nil,mpl::nil,0u>
00148 {
00149 typedef mpl::nil Stream;
00150 typedef mpl::nil Area;
00151 typedef NilLevel Level;
00152 };
00153
00154 template <class T, class A2, class A1>
00155 struct RouteParameters<T,A2,A1,1u>
00156 : public RouteParameters<A2,A1,mpl::nil>
00157 {
00158 typedef RouteParameters<A2,A1,mpl::nil> base;
00159 BOOST_STATIC_ASSERT(( boost::is_same<typename base::Stream, mpl::nil>::value ));
00160 typedef T Stream;
00161 };
00162
00163 template <class T, class A2, class A1>
00164 struct RouteParameters<T,A2,A1,2u>
00165 : public RouteParameters<A2,A1,mpl::nil>
00166 {
00167 typedef RouteParameters<A2,A1,mpl::nil> base;
00168 BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
00169 typedef T Area;
00170 };
00171
00172 template <class T, class A2, class A1>
00173 struct RouteParameters<T,A2,A1,3u>
00174 : public RouteParameters<A2,A1,mpl::nil>
00175 {
00176 typedef RouteParameters<A2,A1,mpl::nil> base;
00177 BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
00178 typedef typename T::SENFLogArea Area;
00179 };
00180
00181 template <class T, class A2, class A1>
00182 struct RouteParameters<T,A2,A1,4u>
00183 : public RouteParameters<A2,A1,mpl::nil>
00184 {
00185 typedef RouteParameters<A2,A1,mpl::nil> base;
00186 BOOST_STATIC_ASSERT(( boost::is_same<typename base::Level, NilLevel>::value ));
00187 typedef T Level;
00188 };
00189
00190 template <class T, class RV>
00191 struct InstanceP
00192 {
00193 static RV * value() { return & T::instance(); }
00194 };
00195
00196 template <class RV>
00197 struct InstanceP<mpl::nil, RV>
00198 {
00199 static RV * value() { return 0; }
00200 };
00201
00202 #endif
00203
00204 }}}
00205
00206
00207 #endif
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218