Utils/Logger: Add syslogFormat option to UDP log target
g0dil [Wed, 18 Feb 2009 10:03:29 +0000 (10:03 +0000)]
Utils/Logger: /sys/log/self command and more command documentation
Scheduler: Add usingHiresTimers() to query current timer source

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1123 270642c3-0616-0410-b53a-bc976706d245

13 files changed:
Scheduler/Scheduler.cci
Scheduler/Scheduler.hh
Scheduler/Scheduler.test.cc
Scheduler/TimerEvent.cci
Scheduler/TimerEvent.ih
Utils/Logger/FileTarget.cc
Utils/Logger/LogFormat.hh
Utils/Logger/SyslogTarget.cc
Utils/Logger/SyslogUDPTarget.cc
Utils/Logger/SyslogUDPTarget.cci
Utils/Logger/SyslogUDPTarget.hh
Utils/Logger/Target.cc
Utils/Logger/Target.ih

index 0549c03..e85c4a5 100644 (file)
@@ -56,13 +56,13 @@ prefix_ unsigned senf::scheduler::hangCount()
 
 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()));
 }
 
@@ -71,6 +71,12 @@ prefix_ bool senf::scheduler::haveScalableHiresTimers()
     return false;
 }
 
+prefix_ bool senf::scheduler::usingHiresTimers()
+{
+    return dynamic_cast<detail::PollTimerSource*>(
+        detail::TimerDispatcher::instance().timerSource()) == 0;
+}
+
 ///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_
 
index fdd5f59..142f8eb 100644 (file)
@@ -258,6 +258,10 @@ namespace scheduler {
      */
     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
@@ -266,7 +270,7 @@ namespace scheduler {
      */
     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
index 8d6a53f..c23b6c9 100644 (file)
@@ -319,6 +319,8 @@ BOOST_AUTO_UNIT_TEST(testScheduler)
 
     BOOST_CHECK( eventCount >= 8u );
 
+    BOOST_CHECK( ! senf::scheduler::usingHiresTimers() );
+
     ///////////////////////////////////////////////////////////////////////////
 
     close(sock);
index e2bf3fb..bbdae19 100644 (file)
@@ -99,11 +99,17 @@ prefix_ bool senf::scheduler::detail::TimerDispatcher::empty()
 }
 
 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_
 
index a6ecf9b..fdb62f2 100644 (file)
@@ -65,7 +65,8 @@ namespace detail {
 
         bool empty() const;
 
-        void setTimerSource(std::auto_ptr<TimerSource> timerSource);
+        void timerSource(std::auto_ptr<TimerSource> timerSource);
+        TimerSource * timerSource();
 
     protected:
 
index e15b3e8..568cc9d 100644 (file)
@@ -81,7 +81,19 @@ prefix_ senf::log::FileTarget::RegisterConsole::RegisterConsole()
 {
     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>
index 8fc4684..4e79978 100644 (file)
@@ -69,9 +69,9 @@ namespace detail {
         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_;
index 40cdd58..b4ba15d 100644 (file)
@@ -62,10 +62,22 @@ prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole()
 
     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>
index e420ec5..cd8d6b3 100644 (file)
 #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)
@@ -48,8 +67,9 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin
     // 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;
@@ -69,6 +89,12 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin
         }
 }
 
+prefix_ void senf::log::SyslogUDPTarget::consoleFormat(std::ostream & os)
+{
+    LogFormat::consoleFormat(os);
+    os << "syslog prefix " << (syslogFormat_ ? "enabled" : "disabled") << "\n";
+}
+
 namespace senf {
 namespace log {
 
@@ -93,7 +119,20 @@ prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole()
              "                  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)>(
index d0a61df..f753955 100644 (file)
 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_
index b940153..25bb893 100644 (file)
@@ -115,17 +115,27 @@ namespace log {
         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 { 
index ca05749..16b00ff 100644 (file)
@@ -407,6 +407,15 @@ prefix_ senf::log::detail::TargetRegistry::TargetRegistry()
              "    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()
@@ -440,6 +449,12 @@ prefix_ void senf::log::detail::TargetRegistry::consoleWrite(LogParameters pm,
     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
 
index 1ad164a..4b81e2e 100644 (file)
 #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 {
 
@@ -90,6 +94,7 @@ 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_;