prefix_ void senf::scheduler::hiresTimers()
{
- detail::TimerDispatcher::instance().setTimerSource(
+ detail::TimerDispatcher::instance().timerSource(
std::auto_ptr<detail::TimerSource>(new detail::POSIXTimerSource()));
}
prefix_ void senf::scheduler::loresTimers()
{
- detail::TimerDispatcher::instance().setTimerSource(
+ detail::TimerDispatcher::instance().timerSource(
std::auto_ptr<detail::TimerSource>(new detail::PollTimerSource()));
}
return false;
}
+prefix_ bool senf::scheduler::usingHiresTimers()
+{
+ return dynamic_cast<detail::PollTimerSource*>(
+ detail::TimerDispatcher::instance().timerSource()) == 0;
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
*/
bool haveScalableHiresTimers();
+ /** \brief Return \c true, if using hires times, \c false otherwise
+ \see hiresTimers() */
+ bool usingHiresTimers();
+
/** \brief Restart scheduler
This call will restart all scheduler dispatchers (timers, signals, file descriptors). This
*/
void restart();
- /** \brief Return \c true, if any event is registered, \c false otherwise. */
+ /** \brief Return \c true, if no event is registered, \c false otherwise. */
bool empty();
/** \brief %scheduler specific time source for Utils/Logger framework
BOOST_CHECK( eventCount >= 8u );
+ BOOST_CHECK( ! senf::scheduler::usingHiresTimers() );
+
///////////////////////////////////////////////////////////////////////////
close(sock);
}
prefix_ void senf::scheduler::detail::TimerDispatcher::
-setTimerSource(std::auto_ptr<TimerSource> timerSource)
+timerSource(std::auto_ptr<TimerSource> timerSource)
{
source_.reset(timerSource.release());
}
+prefix_ senf::scheduler::detail::TimerSource *
+senf::scheduler::detail::TimerDispatcher::timerSource()
+{
+ return source_.get();
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
bool empty() const;
- void setTimerSource(std::auto_ptr<TimerSource> timerSource);
+ void timerSource(std::auto_ptr<TimerSource> timerSource);
+ TimerSource * timerSource();
protected:
{
detail::TargetRegistry::instance().consoleDir().add("file-target",&RegisterConsole::create)
.arg("filename", "name of logfile")
- .doc("Create new file target.");
+ .doc("Create new file target. Examples:\n"
+ "\n"
+ "Create new file target '/var/log/example.log\n"
+ " $ file-target \"/var/log/example.log\"\n"
+ " <Directory '/sys/log/_var_log_example.log'>\n"
+ "\n"
+ "In a configuration file, create new file target '/var/log/example.log' and set\n"
+ "some parameters (If written on one line, this works at the console too:\n"
+ " /sys/log/file-target \"/var/log/example.log\" {\n"
+ " route (IMPORTANT); # route all important messages\n"
+ " timeFormat \"\"; # use non-formatted time format\n"
+ " showArea false; # don't show log area\n"
+ " }\n");
}
prefix_ boost::shared_ptr<senf::console::DirectoryNode>
std::string prefix(time_type timestamp, std::string const & stream,
std::string const & area, unsigned level);
bool isPlainFormat() const;
+ void consoleFormat(std::ostream & os);
private:
- void consoleFormat(std::ostream & os);
std::string tag_;
std::string timeFormat_;
detail::TargetRegistry::instance().consoleDir().add("syslog-target",&RegisterConsole::create)
.arg("facility", "syslog facility to send messages to. One of\n"
- " AUTHPRIV, CRON, DAEMON, FTP, KERN, LPR, MAIL, NEWS, SYSLOG, USER,\n"
- " UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7",
+ " AUTHPRIV CRON DAEMON FTP KERN LPR MAIL NEWS SYSLOG USER\n"
+ " UUCP LOCAL0 LOCAL1 LOCAL2 LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7",
kw::default_value = USER)
- .doc("Create new syslog target.");
+ .doc("Create new syslog target. Examples:\n"
+ "\n"
+ "Create new syslog target\n"
+ " $ syslog-target\n"
+ " <Directory '/sys/log/syslog'>\n"
+ "\n"
+ "In a configuration file, create new syslog target and set some parameters (If\n"
+ "written on one line, this works at the console too:\n"
+ " /sys/log/syslog-target LOCAL2 {\n"
+ " route (IMPORTANT); # route all important messages\n"
+ " timeFormat \"\"; # use non-formatted time format\n"
+ " showArea false; # don't show log area\n"
+ " }\n");
}
prefix_ boost::shared_ptr<senf::console::DirectoryNode>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
+prefix_ void senf::log::SyslogUDPTarget::init()
+{
+ namespace kw = senf::console::kw;
+
+ consoleDir().remove("format");
+ consoleDir().add("format", senf::membind(&SyslogUDPTarget::consoleFormat, this))
+ .doc("Show the current log message format.");
+ consoleDir().add("syslog", senf::membind(
+ static_cast<void (SyslogUDPTarget::*)(bool)>(&SyslogUDPTarget::syslog),
+ this))
+ .arg("flag","new syslog format state",
+ kw::default_value=true)
+ .doc("Change the syslog format flag. By default, syslog formating is enabled. In this\n"
+ "state, the udp target will send out minimal but valid syslog format messages.\n"
+ "\n"
+ "Disabling syslog format will remove the syslog prefix. Log messages will then be\n"
+ "sent using plain UDP.");
+}
+
prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream,
std::string const & area, unsigned level,
std::string const & message)
// The space after the '>' is there on purpose: It ensures, that the prefix (which may be empty)
// or message will not inadvertently be interpreted as date or hostname by a receiving syslog
// daemon or proxy
- prfstream << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> "
- << prefix(timestamp, stream, area, level);
+ if (syslogFormat_)
+ prfstream << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> ";
+ prfstream << prefix(timestamp, stream, area, level);
std::string const & prf (prfstream.str());
typedef boost::char_separator<char> Separator;
}
}
+prefix_ void senf::log::SyslogUDPTarget::consoleFormat(std::ostream & os)
+{
+ LogFormat::consoleFormat(os);
+ os << "syslog prefix " << (syslogFormat_ ? "enabled" : "disabled") << "\n";
+}
+
namespace senf {
namespace log {
" UUCP LOCAL0 LOCAL1 LOCAL2 LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7",
kw::default_value = USER)
.doc("Create new udp target. The {address} can be an IPv4 or IPv6 address. If the port\n"
- "number is omitted, it defaults to the default syslog port 514.");
+ "number is omitted, it defaults to the default syslog port 514. Examples:\n"
+ "\n"
+ "Create new udp target sending messages to the syslog daemon running at localhost\n"
+ " $ udp-target localhost\n"
+ " <Directory '/sys/log/udp-127.0.0.1:514'>\n"
+ "\n"
+ "In a configuration file, create new udp target and set some parameters (If\n"
+ "written on one line, this works at the console too:\n"
+ " /sys/log/udp-target localhost:2345 LOCAL2 {\n"
+ " route (IMPORTANT); # route all important messages\n"
+ " timeFormat \"\"; # use non-formatted time format\n"
+ " showArea false; # don't show log area\n"
+ " syslog false; # no syslog format, just plain udp\n"
+ " }\n");
detail::TargetRegistry::instance().consoleDir().add(
"udp-target",
static_cast<senf::console::DirectoryNode::ptr (*)(INet4Address const &, LogFacility)>(
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4Address const & target,
int facility)
: Target("udp-" + senf::str(target)), LogFormat(consoleDir()), facility_ (facility),
- handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) )
-{}
+ handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) ),
+ syslogFormat_ (true)
+{
+ init();
+}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4SocketAddress const & target,
int facility)
: Target("udp-" + senf::str(target)), LogFormat(consoleDir()), facility_ (facility),
- handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) )
-{}
+ handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) ),
+ syslogFormat_ (true)
+{
+ init();
+}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6Address const & target,
int facility)
: Target("udp-" + senf::str(target)), LogFormat(consoleDir()), facility_ (facility),
- handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) )
-{}
+ handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) ),
+ syslogFormat_ (true)
+{
+ init();
+}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6SocketAddress const & target,
int facility)
: Target("udp-" + senf::str(target)), LogFormat(consoleDir()), facility_ (facility),
- handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) )
-{}
+ handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) ),
+ syslogFormat_ (true)
+{
+ init();
+}
+
+prefix_ bool senf::log::SyslogUDPTarget::syslog()
+ const
+{
+ return syslogFormat_;
+}
+
+prefix_ void senf::log::SyslogUDPTarget::syslog(bool enabled)
+{
+ syslogFormat_ = enabled;
+}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
using detail::LogFormat::timeFormat;
using detail::LogFormat::tag;
+ bool syslog() const; ///< \c true, if using syslog format, \c false otherwise
+ /**< When syslog format is disabled, messages are not
+ formated as valid syslog messages but sent using plain
+ UDP. */
+ void syslog(bool enabled=true); /// Set syslog format
+
private:
+ void init();
void v_write(time_type timestamp, std::string const & stream,
std::string const & area, unsigned level,
std::string const & message);
+ void consoleFormat(std::ostream & os);
+
int facility_;
typedef senf::ClientSocketHandle< senf::MakeSocketPolicy<
senf::DatagramFramingPolicy,
senf::ConnectedCommunicationPolicy,
senf::WriteablePolicy>::policy > Handle;
Handle handle_;
+ bool syslogFormat_;
public:
enum LogFacility {
" message (senf::log::DefaultArea NOTICE) \"Test notice\";\n"
" message (FATAL) \"Program on fire\";\n"
" message (VERBOSE senf::log::Debug) \"Debug message\";");
+ consoleDir_().add("self", senf::membind(&TargetRegistry::consoleSelf, this))
+ .doc("Get the log directory of the current network client. Example usage:\n"
+ "\n"
+ "Just get the log config directory\n"
+ " $ /sys/log/self\n"
+ " <Directory '/sys/log/client-xxx.xxx.xxx.xxx:xxx'>\n"
+ "\n"
+ "Route all messages to the currently connected client\n"
+ " $ /sys/log/self { route (); }");
}
prefix_ senf::log::detail::TargetRegistry::~TargetRegistry()
write(*pm.stream, *pm.area, pm.level, msg);
}
+prefix_ boost::shared_ptr<senf::console::DirectoryNode>
+senf::log::detail::TargetRegistry::consoleSelf(std::ostream & os)
+{
+ return senf::console::Client::get(os).consoleDir().node().thisptr();
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::log::detail::LogParameters
#include <memory>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
#include "../Console/LazyDirectory.hh"
#include "../Console/Parse.hh"
///////////////////////////////ih.p////////////////////////////////////////
namespace senf {
+
+ namespace console { class DirectoryNode; }
+
namespace log {
namespace detail {
void consoleStreams(std::ostream & os);
void consoleWrite(LogParameters parameters, std::string const & msg);
void consoleRemoveTarget(Target * target);
+ boost::shared_ptr<senf::console::DirectoryNode> consoleSelf(std::ostream & os);
typedef std::set<Target *> Targets;
Targets targets_;