Skip to content
Snippets Groups Projects
Commit fbd9e4d1 authored by g0dil's avatar g0dil
Browse files

Utils/Logger: Correct newline handling in IOStreamLogger

Utils/Logger: Completed the target routing and querying API
parent 08952c5b
No related branches found
No related tags found
No related merge requests found
......@@ -28,6 +28,8 @@
// Custom includes
#include <locale>
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
//#include "IOStreamTarget.mpp"
#define prefix_
......@@ -41,7 +43,8 @@ prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os)
{
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")) );
}
////////////////////////////////////////
......@@ -52,10 +55,25 @@ prefix_ void senf::log::IOStreamTarget::v_write(boost::posix_time::ptime timesta
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////////////////////////////////////////
......
......@@ -46,11 +46,89 @@ prefix_ senf::log::Target::~Target()
// 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)
{
......@@ -72,10 +150,10 @@ prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * st
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;
}
......@@ -93,10 +171,10 @@ prefix_ void senf::log::Target::write(boost::posix_time::ptime timestamp,
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;
}
......
......@@ -34,88 +34,62 @@
///////////////////////////////////////////////////////////////////////////
// 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_;
}
///////////////////////////////////////////////////////////////////////////
......
......@@ -35,21 +35,39 @@
// 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);
}
////////////////////////////////////////
......@@ -57,16 +75,30 @@ prefix_ void senf::log::Target::route(action_t 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);
}
///////////////////////////////////////////////////////////////////////////
......
......@@ -62,6 +62,34 @@ namespace log {
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
///@{
......@@ -71,45 +99,48 @@ namespace log {
///@}
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);
......@@ -128,21 +159,6 @@ namespace log {
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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment