X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FLogger%2FTarget.cc;h=c07ba211cc32349cb2857dcc8a5fbfe35366ceb9;hb=ac86c2bb40746fbedf70a19af3307e5da642b04a;hp=651671e84c93c8d3f2c35151ec41fad107d40cfc;hpb=9ff976ea47b175355a1f7ef4d05f14edb98a82e4;p=senf.git diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 651671e..c07ba21 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -27,6 +27,7 @@ //#include "Target.ih" // Custom includes +#include //#include "Target.mpp" #define prefix_ @@ -35,24 +36,177 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::Target +prefix_ senf::log::Target::Target() +{ + TargetRegistry::instance().registerTarget(this); +} + prefix_ senf::log::Target::~Target() -{} +{ + while( ! rib_.empty()) { + // This is terribly slow but simplifies the area cache handling and removing a target should + // be quite seldom + RIB::reverse_iterator i (rib_.rbegin()); + unroute(i->stream_, i->area_, i->level_, i->action_); + } + TargetRegistry::instance().unregisterTarget(this); +} + +prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area, + unsigned level, action_t action, int index) +{ + detail::StreamBase const * s (StreamRegistry::instance().lookup(stream)); + if (!s) + throw InvalidStreamException(); + detail::AreaBase const * a (0); + if (! area.empty()) { + a = AreaRegistry::instance().lookup(area); + if (!a) + throw InvalidAreaException(); + } + route(s, a, level, action, index); +} + +prefix_ void senf::log::Target::unroute(std::string const & stream, std::string const & area, + unsigned level, action_t action) +{ + detail::StreamBase const * s (StreamRegistry::instance().lookup(stream)); + if (!s) + throw InvalidStreamException(); + detail::AreaBase const * a (0); + if (! area.empty()) { + a = AreaRegistry::instance().lookup(area); + if (!a) + throw InvalidAreaException(); + } + unroute(s, a, level, action); +} + +prefix_ void senf::log::Target::unroute(int index) +{ + RIB::iterator i; + if (index < 0) { + if (RIB::size_type(-index) >= rib_.size()) + i = rib_.begin(); + else { + i = rib_.end(); + std::advance(i, -index); + } + } else { + if (RIB::size_type(index+1) >= rib_.size()) { + i = rib_.end(); + --i; + } else { + i = rib_.begin(); + std::advance(i, index); + } + } + RoutingEntry entry (*i); + rib_.erase(i); + if (entry.action_ == ACCEPT) + updateRoutingCache(entry.stream_, entry.area_); +} + +//////////////////////////////////////// +// private members + +prefix_ void senf::log::Target::route(detail::StreamBase const * stream, + detail::AreaBase const * area, unsigned level, + action_t action, int index) +{ + RIB::iterator i; + if (index < 0) { + if (RIB::size_type(-index-1) >= rib_.size()) + i = rib_.begin(); + else { + i = rib_.end(); + std::advance(i, index + 1 ); + } + } else { + if (RIB::size_type(index) >= rib_.size()) + i = rib_.end(); + else { + i = rib_.begin(); + std::advance(i, index); + } + } + rib_.insert(i, RoutingEntry(stream, area, level, action)); + if (action == ACCEPT) + updateRoutingCache(stream, area); +} + +prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream, + detail::AreaBase const * area, unsigned level, + action_t action) +{ + RIB::iterator i = std::find(rib_.begin(), rib_.end(), + RoutingEntry(stream, area, level, action)); + if (i != rib_.end()) + unroute(std::distance(rib_.begin(), i)); +} + +prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * stream, + detail::AreaBase const * area) +{ + if (! stream) { + StreamRegistry::Registry::iterator i (StreamRegistry::instance().registry_.begin()); + StreamRegistry::Registry::iterator const i_end (StreamRegistry::instance().registry_.end()); + for (; i != i_end ; ++i) + updateRoutingCache(i->second, area); + return; + } + if (! area) { + AreaRegistry::Registry::iterator i (AreaRegistry::instance().registry_.begin()); + AreaRegistry::Registry::iterator const i_end (AreaRegistry::instance().registry_.end()); + for (; i != i_end ; ++i) + updateRoutingCache(stream, i->second); + return; + } + unsigned limit (DISABLED::value); + RIB::iterator i (rib_.begin()); + RIB::iterator const i_end (rib_.end()); + for(; i != i_end; ++i) + if ( (! i->stream_ || i->stream_ == stream) && + (! i->area_ || i->area_ == area) && + i->action_ == ACCEPT ) { + unsigned l (i->level_ == NONE::value ? i->stream_->defaultRuntimeLimit() : i->level_); + if (l < limit) + limit = l; + } + if (limit == DISABLED::value) + area->removeRoutingCache(*this, *stream); + else + area->updateRoutingCache(*this, *stream, limit); +} -prefix_ void senf::log::Target::write(detail::StreamBase const & stream, - detail::AreaBase const & area, - unsigned level, std::string const & message) +prefix_ void senf::log::Target::write(boost::posix_time::ptime timestamp, + detail::StreamBase const & stream, + detail::AreaBase const & area, unsigned level, + std::string const & message) { RIB::iterator i (rib_.begin()); RIB::iterator const i_end (rib_.end()); for (; i != i_end; ++i) - if ( ( ! i->stream || i->stream == &stream ) && - ( ! i->area || i->area == &area ) && - i->level <= level ) { - v_write(stream.v_name(), area.v_name(), level, message); + if ( (! i->stream_ || i->stream_ == &stream) && + (! i->area_ || i->area_ == &area) && + (i->level_ == NONE::value ? i->stream_->defaultRuntimeLimit() : i->level_) <= level ) { + if (i->action_ == ACCEPT) + v_write(timestamp, stream.v_name(), area.v_name(), level, message); return; } } +/////////////////////////////////////////////////////////////////////////// +// senf::log::TargetRegistry + +prefix_ void senf::log::TargetRegistry::write(detail::StreamBase const & stream, + detail::AreaBase const & area, unsigned level, + std::string msg) +{ + boost::posix_time::ptime timestamp (boost::posix_time::microsec_clock::universal_time()); + area.write(timestamp, stream, level, msg); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Target.mpp"