22 #include <boost/format.hpp> 41 (VERBOSE)(NOTICE)(MESSAGE)(IMPORTANT)(CRITICAL)(FATAL) );
47 namespace kw = console::kw;
48 namespace fty = console::factory;
50 detail::TargetRegistry::instance().registerTarget(
this, name);
52 .add(
"list", fty::Command(&Target::consoleList,
this)
53 .doc(
"Show routing table\n" 57 " STREAM stream to match, empty to match all streams\n" 58 " AREA area to match, empty to match all targets\n" 59 " LEVEL match messages with level above this. Log levels in increasing order\n" 61 " verbose, notice, message, important, critical, fatal\n" 62 " If the log level is listed as 'default', the streams default limit\n" 64 " ACTION action to take: accept or reject") );
66 .add(
"route", fty::Command(&Target::consoleRoute,
this)
67 .arg(
"index",
"index at which to insert new rule")
68 .arg(
"parameters",
"log parameters. The log parameters select the log stream, log area\n" 69 " and log level. You may specify any combination of these parameters\n" 70 " in any order. Use the '/sys/log/stream' and '/sys/log/areas' commands\n" 71 " to list all valid streams and areas. Valid log levels are:\n" 72 " VERBOSE NOTICE MESSAGE IMPORTANT CRITICAL FATAL")
73 .arg(
"action",
"routing action, one of: ACCEPT, REJECT",
74 kw::default_value=ACCEPT)
75 .doc(
"Add routing entry. Log messages are matched against the routing table beginning\n" 76 "with the first entry. The action of the first matching entry determines the\n" 77 "handling of the message.\n" 82 " route all messages with level above each streams default log limit to this\n" 85 " route 1 (my::Class VERBOSE)\n" 86 " route all messages which are in the my::Class area. Insert this route after\n" 89 " route (senf::log::Debug VERBOSE) REJECT\n" 91 " route all messages not in the senf::log::Debug stream to the current area.\n" 93 "The additional optional index argument identifies the position in the routing table\n" 94 "where the new routing entry will be added. Positive numbers count from the\n" 95 "beginning, 0 being the first routing entry. Negative values count from the end.") );
97 .add(
"route", fty::Command<
void (detail::LogParameters,
action_t)>(
98 boost::bind(&Target::consoleRoute,
this, -1, _1, _2))
100 .arg(
"action", kw::default_value=ACCEPT) );
104 .arg(
"index",
"index of routing entry to remove")
105 .overloadDoc(
"Remove routing entry with the given index") );
107 .add(
"unroute", fty::Command(&Target::consoleUnroute,
this)
108 .arg(
"parameters",
"log parameters. The log parameters select the log stream, log area\n" 109 " and log level. You may specify any combination of these parameters\n" 110 " in any order. Use the '/sys/log/stream' and '/sys/log/areas' commands\n" 111 " to list all valid streams and areas. Valid log levels are:\n" 112 " VERBOSE NOTICE MESSAGE IMPORTANT CRITICAL FATAL")
113 .arg(
"action",
"routing action, one of: ACCEPT, REJECT",
114 kw::default_value=ACCEPT)
115 .overloadDoc(
"Remove the routing entry matching the specified arguments.") );
118 .doc(
"Remove all routing entries clearing the routing table. This will disable all\n" 119 "logging output on this target.") );
124 while (! rib_.empty()) {
127 RIB::reverse_iterator i (rib_.rbegin());
128 unroute(i->stream_, i->area_, i->level_, i->action_);
130 detail::TargetRegistry::instance().unregisterTarget(
this);
134 unsigned level,
action_t action,
int index)
136 detail::StreamBase
const * s (0);
137 if (! stream.empty()) {
142 detail::AreaBase
const * a (0);
143 if (! area.empty()) {
148 route(s, a, level, action, index);
154 detail::StreamBase
const * s (0);
155 if (! stream.empty()) {
160 detail::AreaBase
const * a (0);
161 if (! area.empty()) {
166 unroute(s, a, level, action);
175 if (RIB::size_type(-index) >= rib_.size())
179 std::advance(i, index);
182 if (RIB::size_type(index+1) >= rib_.size()) {
187 std::advance(i, index);
194 if (entry.action_ == ACCEPT)
195 updateRoutingCache(entry.stream_, entry.area_);
202 RIB::const_iterator i (old.begin());
203 RIB::const_iterator
const i_end (old.end());
204 for (; i != i_end; ++i)
205 if (i->action_ == ACCEPT)
206 updateRoutingCache(i->stream_, i->area_);
214 return consoleDir_();
221 detail::AreaBase
const * area,
unsigned level,
226 if (RIB::size_type(-index-1) >= rib_.size())
230 std::advance(i, index + 1 );
233 if (RIB::size_type(index) >= rib_.size())
237 std::advance(i, index);
240 rib_.insert(i,
RoutingEntry(stream, area, level, action));
241 if (action == ACCEPT)
242 updateRoutingCache(stream, area);
244 detail::TargetRegistry::instance().routed();
248 detail::AreaBase
const * area,
unsigned level,
251 RIB::iterator i = std::find(rib_.begin(), rib_.end(),
254 unroute(std::distance(rib_.begin(), i));
257 prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase
const * stream,
258 detail::AreaBase
const * area)
263 for (; i != i_end ; ++i)
264 updateRoutingCache(i->second, area);
270 for (; i != i_end ; ++i)
271 updateRoutingCache(stream, i->second);
278 RIB::iterator i (rib_.begin());
279 RIB::iterator
const i_end (rib_.end());
280 for (; i != i_end; ++i)
281 if ( (! i->stream_ || i->stream_ == stream) &&
282 (! i->area_ || i->area_ == area) &&
283 i->action_ == ACCEPT ) {
284 unsigned l (i->level_ ==
NONE::value ? stream->defaultRuntimeLimit() : i->level_);
289 area->removeRoutingCache(*
this, *stream);
291 area->updateRoutingCache(*
this, *stream, limit);
295 detail::StreamBase
const & stream,
296 detail::AreaBase
const & area,
unsigned level,
297 std::string
const & message)
299 RIB::iterator i (rib_.begin());
300 RIB::iterator
const i_end (rib_.end());
301 for (; i != i_end; ++i)
302 if ( (! i->stream_ || i->stream_ == &stream) &&
303 (! i->area_ || i->area_ == &area) &&
304 (i->level_ ==
NONE::value ? stream.defaultRuntimeLimit() : i->level_) <= level ) {
305 if (i->action_ == ACCEPT)
306 v_write(timestamp, stream.v_name(), area.v_name(), level, message);
312 std::string formatLabel(std::string
const & l)
317 return l.substr(l.size()-29);
321 char const * levelNames[] = {
322 "NONE",
"VERBOSE",
"NOTICE",
"MESSAGE",
"IMPORTANT",
"CRITICAL",
"FATAL",
"DISABLED" };
324 char const * levelNamesList[] = {
325 "default",
"verbose",
"notice",
"message",
"important",
"critical",
"fatal",
"disabled" };
328 prefix_ void senf::log::Target::consoleList(std::ostream & os)
331 boost::format fmt (
"%2d %-29s %-29s %-9s %-6s\n");
332 os << fmt %
"#" %
"STREAM" %
"AREA" %
"LEVEL" %
"ACTION";
334 for (
iterator i (begin()); i != end(); ++i, ++n)
337 % formatLabel(i->stream())
338 % formatLabel(i->area())
339 % levelNamesList[i->level()]
340 % (i->action() == ACCEPT ?
"accept" :
"reject");
343 prefix_ void senf::log::Target::consoleRoute(
int index, detail::LogParameters
const & pm,
action_t action)
345 route(pm.stream, pm.area, pm.level, action, index);
348 prefix_ void senf::log::Target::consoleUnroute(detail::LogParameters
const & pm,
action_t action)
350 unroute(pm.stream, pm.area, pm.level, action);
356 prefix_ void senf::log::detail::TargetRegistry::dynamicTarget(std::unique_ptr<Target> target)
358 namespace fty = console::factory;
361 .add(
"remove", fty::Command<
void ()>(
362 boost::bind(&TargetRegistry::consoleRemoveTarget,
this, target.get()))
363 .doc(
"Remove target.") );
364 dynamicTargets_.insert(target.release());
367 prefix_ void senf::log::detail::TargetRegistry::registerTarget(
Target * target,
368 std::string
const &
name)
370 targets_.insert(target);
371 consoleDir_().add(name, target->consoleDir_());
374 prefix_ void senf::log::detail::TargetRegistry::write(StreamBase
const & stream,
375 AreaBase
const & area,
unsigned level,
376 std::string
const & msg)
378 if (fallbackRouting_) {
379 if (level >= stream.defaultRuntimeLimit())
387 prefix_ void senf::log::detail::TargetRegistry::consoleRemoveTarget(
Target * target)
389 dynamicTargets_.erase(target);
393 prefix_ senf::log::detail::TargetRegistry::TargetRegistry()
394 : fallbackRouting_(
true)
396 namespace kw = console::kw;
397 namespace fty = console::factory;
399 console::sysdir().add(
"log", consoleDir_());
401 .add(
"areas", fty::Command(&TargetRegistry::consoleAreas,
this)
402 .doc(
"List all areas") );
404 .add(
"streams", fty::Command(&TargetRegistry::consoleStreams,
this)
405 .doc(
"List all streams with the streams default runtime log level limit.") );
407 .add(
"message", fty::Command(&TargetRegistry::consoleWrite,
this)
408 .arg(
"parameters",
"log parameters. The log parameters select the log stream, log area\n" 409 " and log level. You may specify any combination of these parameters\n" 410 " in any order. Use the '/sys/log/stream' and '/sys/log/areas' commands\n" 411 " to list all valid streams and areas. Valid log levels are:\n" 412 " VERBOSE NOTICE MESSAGE IMPORTANT CRITICAL FATAL",
413 kw::default_value = LogParameters::defaultParameters())
414 .arg(
"message",
"message to write")
415 .doc(
"Write log message.\n" 418 " message \"Test\";\n" 419 " message (senf::log::DefaultArea NOTICE) \"Test notice\";\n" 420 " message (FATAL) \"Program on fire\";\n" 421 " message (VERBOSE senf::log::Debug) \"Debug message\";") );
423 .add(
"self", fty::Command(&TargetRegistry::consoleSelf,
this)
424 .doc(
"Get the log directory of the current network client. Example usage:\n" 426 "Just get the log config directory\n" 428 " <Directory '/sys/log/client-xxx.xxx.xxx.xxx:xxx'>\n" 430 "Route all messages to the currently connected client\n" 431 " $ /sys/log/self { route () ); }") );
434 prefix_ senf::log::detail::TargetRegistry::~TargetRegistry()
436 Targets::iterator i (dynamicTargets_.begin());
437 Targets::iterator
const i_end (dynamicTargets_.end());
438 for (; i != i_end; ++i)
442 prefix_ void senf::log::detail::TargetRegistry::consoleAreas(std::ostream & os)
446 for (; i != i_end; ++i)
450 prefix_ void senf::log::detail::TargetRegistry::consoleStreams(std::ostream & os)
454 for (; i != i_end; ++i) {
460 prefix_ void senf::log::detail::TargetRegistry::consoleWrite(LogParameters pm,
461 std::string
const & msg)
464 write(*pm.stream, *pm.area, pm.level, msg);
467 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
468 senf::log::detail::TargetRegistry::consoleSelf(std::ostream & os)
483 prefix_ void senf::log::detail::LogParameters::setDefaults()
486 stream = & senf::log::Debug::instance();
488 area = & senf::log::DefaultArea::instance();
493 prefix_ senf::log::detail::LogParameters senf::log::detail::LogParameters::defaultParameters()
508 else os <<
"unknown action";
514 void parseParamToken(std::string
const & value, senf::log::detail::LogParameters & out)
516 senf::log::detail::StreamBase
const * s (
525 senf::log::detail::AreaBase
const * a (
535 std::find(levelNames+1, levelNames+
sizeof(levelNames)/
sizeof(levelNames[0])-1, value));
536 if (i == levelNames+
sizeof(levelNames)/
sizeof(levelNames[0])-1)
540 out.level = i-levelNames;
546 LogParameters
const & pm)
550 os << pm.stream->v_name();
552 if (pm.stream) os <<
' ';
553 os << pm.area->v_name();
556 if (pm.stream || pm.area) os <<
' ';
557 os << levelNames[pm.level];
563 prefix_ void senf::log::detail::
569 for (console::ParseCommandInfo::TokensRange::iterator i (tokens.begin());
570 i != tokens.end(); ++i)
571 parseParamToken(i->value(), out);
578 senf::log::FileTarget::RegisterConsole senf::log::FileTarget::RegisterConsole::instance;
579 senf::log::SyslogTarget::RegisterConsole senf::log::SyslogTarget::RegisterConsole::instance;
580 senf::log::SyslogUDPTarget::RegisterConsole senf::log::SyslogUDPTarget::RegisterConsole::instance;
static AreaRegistry & instance()
Access area registry singleton instance.
static unsigned const value
static unsigned const value
static AreaRegistry & instance()
Access stream registry singleton instance.
std::ostream & operator<<(std::ostream &os, Packet const &packet)
SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogTarget, LogFacility,(AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG)(USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5)(LOCAL6)(LOCAL7))
static Client & get(std::ostream &os)
void flush()
Clear routing table.
senf::console::ScopedDirectory & consoleDir()
Get console/config directory.
Exception: Invalid stream.
static unsigned const value
ConsoleTarget public header.
iterator begin()
Beginning of area name sequence.
boost::transform_iterator< SelectName, Registry::const_iterator > iterator
Iterator type.
detail::AreaBase const * lookup(std::string const &name)
iterator end()
End of area name sequence.
static ConsoleTarget & instance()
void unroute(action_t action=ACCEPT)
Remove route (static)
boost::iterator_range< token_iterator > TokensRange
SENF_CONSOLE_REGISTER_ENUM_MEMBER(TargetRegistry, Level,(VERBOSE)(NOTICE)(MESSAGE)(IMPORTANT)(CRITICAL)(FATAL))
RIB::const_iterator iterator
Routing table iterator.
unspecified_keyword_type name
config::time_type time_type
void route(action_t action=ACCEPT, int index=-1)
Add route (static)
boost::transform_iterator< ::__gnu_cxx::select1st< Registry::value_type >, Registry::const_iterator > iterator
::phoenix::function< detail::clear > const clear
Logging target base class.
Target(std::string const &name)