// Custom includes
#include <locale>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/tokenizer.hpp>
//#include "IOStreamTarget.mpp"
#define prefix_
{
std::locale const & loc (stream_.getloc());
if (!std::has_facet<boost::posix_time::time_facet>(loc))
- stream_.imbue( std::locale(loc, new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S.%f-0000")) );
+ stream_.imbue( std::locale(
+ loc, new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S.%f-0000")) );
}
////////////////////////////////////////
std::string const & area, unsigned level,
std::string const & message)
{
- stream_ << timestamp << " ";
- if (! area.empty())
- stream_ << "[" << area << "] ";
- stream_ << message << std::endl;
+ std::string m (boost::trim_right_copy(message));
+
+ typedef boost::char_separator<char> Separator;
+ typedef boost::tokenizer<Separator> Tokenizer;
+ Separator separator ("\n");
+ Tokenizer tokenizer (m, separator);
+ Tokenizer::iterator i (tokenizer.begin());
+ Tokenizer::iterator const i_end (tokenizer.end());
+
+ char sep (' ');
+
+ for (; i != i_end; ++i) {
+ stream_ << timestamp << sep;
+ if (! area.empty())
+ stream_ << "[" << area << "] ";
+ stream_ << *i << "\n";
+ sep = '-';
+ }
+ stream_ << std::flush;
}
///////////////////////////////cc.e////////////////////////////////////////
// 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);
+ 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(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)
{
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 ( (! 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;
}
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 == NONE::value ? i->stream->defaultRuntimeLimit() : i->level) <= level ) {
- if (i->action == ACCEPT)
+ 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::Target
-prefix_ void senf::log::Target::route(std::string const & stream, action_t action)
+prefix_ iterator senf::log::Target::begin()
+ const
{
- detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
- if (!s)
- throw InvalidStreamException();
- route(s, 0, NONE::value, action);
+ return rib_.begin();
}
-prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area,
- action_t action)
+prefix_ iterator senf::log::Target::end()
+ const
{
- detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
- if (!s)
- throw InvalidStreamException();
- detail::AreaBase const * a (AreaRegistry::instance().lookup(area));
- if (!a)
- throw InvalidAreaException();
- route(s, a, NONE::value, action);
-}
-
-prefix_ void senf::log::Target::route(std::string const & stream, unsigned level, action_t action)
-{
- detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
- if (!s)
- throw InvalidStreamException();
- route(s, 0, level, action);
-}
-
-prefix_ void senf::log::Target::route(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 (AreaRegistry::instance().lookup(area));
- if (!a)
- throw InvalidAreaException();
- route(s, a, level, action);
-}
-
-////////////////////////////////////////
-// private members
-
-prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
- detail::AreaBase const * area, unsigned level,
- action_t action)
-{
- rib_.push_back(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_.erase(std::remove(rib_.begin(), rib_.end(), RoutingEntry(stream, area, level, action)),
- rib_.end());
- if (action == ACCEPT)
- updateRoutingCache(stream, area);
+ return rib_.end();
}
///////////////////////////////////////////////////////////////////////////
// senf::log::Target::RoutingEntry
-prefix_ senf::log::Target::RoutingEntry::RoutingEntry(detail::StreamBase const * stream_,
- detail::AreaBase const * area_,
- unsigned level_, action_t action_)
- : stream(stream_), area(area_), level(level_), action(action_)
+prefix_ senf::log::Target::RoutingEntry::RoutingEntry(detail::StreamBase const * stream,
+ detail::AreaBase const * area,
+ unsigned level, action_t action)
+ : stream_(stream), area_(area), level_(level), action_(action)
{}
prefix_ senf::log::Target::RoutingEntry::RoutingEntry()
- : stream(0), area(0), level(0), action(ACCEPT)
+ : stream_(0), area_(0), level_(0), action_(ACCEPT)
{}
prefix_ bool senf::log::Target::RoutingEntry::operator==(RoutingEntry const & other)
{
return
- stream == other.stream &&
- area == other.area &&
- level == other.level &&
- action == other.action;
+ stream_ == other.stream_ &&
+ area_ == other.area_ &&
+ level_ == other.level_ &&
+ action_ == other.action_;
+}
+
+prefix_ std::string senf::log::Target::RoutingEntry::stream()
+ const
+{
+ return stream_->v_name();
+}
+
+prefix_ std::string senf::log::Target::RoutingEntry::area()
+ const
+{
+ return area_->v_name();
+}
+
+prefix_ unsigned senf::log::Target::RoutingEntry::level()
+ const
+{
+ return level_;
+}
+
+prefix_ senf::log::Target::action_t senf::log::Target::RoutingEntry::action()
+ const
+{
+ return action_;
}
///////////////////////////////////////////////////////////////////////////
// senf::log::Target
template <class Stream>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
{
- route(&Stream::instance(), 0, NONE::value, action);
+ route(&Stream::instance(), 0, NONE::value, action, index);
}
template <class Stream, class Arg>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
{
- route<Arg>(&Stream::instance(), static_cast<Arg*>(0), action);
+ route<Arg>(&Stream::instance(), static_cast<Arg*>(0), action, index);
}
template <class Stream, class Area, class Level>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
{
- route(&Stream::instance(), &Area::instance(), Level::value, action);
+ route(&Stream::instance(), &Area::instance(), Level::value, action, index);
+}
+
+template <class Stream>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+ unroute(&Stream::instance(), 0, NONE::value, action);
+}
+
+template <class Stream, class Arg>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+ unroute<Arg>(&Stream::instance(), static_cast<Arg*>(0), action);
+}
+
+template <class Stream, class Area, class Level>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+ unroute(&Stream::instance(), &Area::instance(), Level::value, action);
}
////////////////////////////////////////
template <class Area>
prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
- detail::AreaBase const *, action_t action)
+ detail::AreaBase const *, action_t action, int index)
{
- route(stream, &Area::instance(), NONE::value, action);
+ route(stream, &Area::instance(), NONE::value, action, index);
}
template <class Level>
prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
- detail::LevelBase const *, action_t action)
+ detail::LevelBase const *, action_t action, int index)
+{
+ route(stream, 0, Level::value, action, index);
+}
+
+template <class Area>
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+ detail::AreaBase const *, action_t action)
+{
+ unroute(stream, &Area::instance(), NONE::value, action);
+}
+
+template <class Level>
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+ detail::LevelBase const *, action_t action)
{
- route(stream, 0, Level::value, action);
+ unroute(stream, 0, Level::value, action);
}
///////////////////////////////////////////////////////////////////////////
enum action_t { ACCEPT, REJECT };
+ struct RoutingEntry
+ {
+ RoutingEntry();
+ bool operator==(RoutingEntry const & other);
+
+ std::string stream() const;
+ std::string area() const;
+ unsigned level() const;
+ action_t action() const;
+
+ private:
+ RoutingEntry(detail::StreamBase const * stream, detail::AreaBase const * area,
+ unsigned level, action_t action);
+
+ detail::StreamBase const * stream_;
+ detail::AreaBase const * area_;
+ unsigned level_;
+ action_t action_;
+
+ friend class Target;
+ };
+
+ private:
+ typedef std::vector<RoutingEntry> RIB;
+
+ public:
+ typedef RIB::const_iterator iterator;
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
///@}
- template <class Stream>
- void route(action_t action=ACCEPT);
+ template <class Stream> void route(action_t action = ACCEPT, int index = -1);
+ template <class Stream, class Arg> void route(action_t action = ACCEPT, int index = -1);
+ template <class Stream, class Area, class Level> void route(action_t action = ACCEPT,
+ int index = -1);
- template <class Stream, class Arg>
- void route(action_t action=ACCEPT);
+ void route(std::string const & stream, std::string const & area = "",
+ unsigned level = NONE::value, action_t action = ACCEPT, int index = -1);
- template <class Stream, class Area, class Level>
- void route(action_t action=ACCEPT);
+ template <class Stream> void unroute(action_t action = ACCEPT);
+ template <class Stream, class Arg> void unroute(action_t action = ACCEPT);
+ template <class Stream, class Area, class Level> void unroute(action_t action = ACCEPT);
- void route(std::string const & stream, action_t action=ACCEPT);
- void route(std::string const & stream, std::string const & area, action_t action=ACCEPT);
- void route(std::string const & stream, unsigned level, action_t action=ACCEPT);
- void route(std::string const & stream, std::string const & area, unsigned level,
- action_t action=ACCEPT);
+ void unroute(std::string const & stream, std::string const & area = "",
+ unsigned level = NONE::value, action_t action = ACCEPT);
+ void unroute(int index);
struct InvalidStreamException : public std::exception
{ virtual char const * what() const throw()
{ return "senf::log::Target::InvalidStreamException"; } };
-
+
struct InvalidAreaException : public std::exception
{ virtual char const * what() const throw()
{ return "senf::log::Target::InvalidAreaException"; } };
-
- protected:
-
- std::string timestamp();
+ iterator begin() const;
+ iterator end() const;
+
private:
-
void route(detail::StreamBase const * stream, detail::AreaBase const * area,
- unsigned level, action_t action);
+ unsigned level, action_t action, int index);
void unroute(detail::StreamBase const * stream, detail::AreaBase const * area,
unsigned level, action_t action);
- template <class Area>
- void route(detail::StreamBase const * stream, detail::AreaBase const *, action_t action);
+ template <class Area> void route(detail::StreamBase const * stream,
+ detail::AreaBase const *, action_t action, int index);
+ template <class Level> void route(detail::StreamBase const * stream,
+ detail::LevelBase const *, action_t action, int index);
- template <class Level>
- void route(detail::StreamBase const * stream, detail::LevelBase const *, action_t action);
+ template <class Area> void unroute(detail::StreamBase const * stream,
+ detail::AreaBase const *, action_t action);
+ template <class Level> void unroute(detail::StreamBase const * stream,
+ detail::LevelBase const *, action_t action);
void updateRoutingCache(detail::StreamBase const * stream, detail::AreaBase const * area);
private:
# endif
- struct RoutingEntry
- {
- RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_,
- unsigned level_, action_t action_);
- RoutingEntry();
-
- bool operator==(RoutingEntry const & other);
-
- detail::StreamBase const * stream;
- detail::AreaBase const * area;
- unsigned level; action_t action;
- };
-
- typedef std::vector<RoutingEntry> RIB;
-
RIB rib_;
friend class detail::AreaBase;