00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "SyslogUDPTarget.hh"
00027
00028
00029
00030 #include <sstream>
00031 #include <boost/algorithm/string/trim.hpp>
00032 #include <boost/tokenizer.hpp>
00033 #include <senf/Utils/Console/ParsedCommand.hh>
00034 #include <senf/Utils/Console/Traits.hh>
00035 #include <senf/Utils/Console/ScopedDirectory.hh>
00036
00037
00038 #define prefix_
00039
00040
00041 prefix_ void senf::log::SyslogUDPTarget::init()
00042 {
00043 namespace kw = console::kw;
00044 namespace fty = console::factory;
00045
00046 consoleDir().remove("format");
00047 consoleDir()
00048 .add("format", fty::Command(&SyslogUDPTarget::consoleFormat, this)
00049 .doc("Show the current log message format.") );
00050 consoleDir()
00051 .add("syslog", fty::Command(SENF_MEMBINDFNP(void, SyslogUDPTarget, syslog, (bool)))
00052 .arg("flag","new syslog format state",
00053 kw::default_value=true)
00054 .doc("Change the syslog format flag. By default, syslog formating is enabled. In this\n"
00055 "state, the udp target will send out minimal but valid syslog format messages.\n"
00056 "\n"
00057 "Disabling syslog format will remove the syslog prefix. Log messages will then be\n"
00058 "sent using plain UDP.") );
00059 }
00060
00061 prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream,
00062 std::string const & area, unsigned level,
00063 std::string const & message)
00064 {
00065 std::string m (message);
00066 boost::trim_right(m);
00067 detail::quoteNonPrintable(m);
00068
00069 std::stringstream prfstream;
00070
00071
00072
00073 if (syslogFormat_)
00074 prfstream << '<' << (facility_ | SyslogTarget::LEVELMAP[level]) << "> ";
00075 prfstream << prefix(timestamp, stream, area, level);
00076 std::string const & prf (prfstream.str());
00077
00078 typedef boost::char_separator<char> Separator;
00079 typedef boost::tokenizer<Separator> Tokenizer;
00080 Separator separator ("\n");
00081 Tokenizer tokenizer (m, separator);
00082 Tokenizer::iterator i (tokenizer.begin());
00083 Tokenizer::iterator const i_end (tokenizer.end());
00084
00085 std::string line;
00086 unsigned sz (896-prf.size());
00087 for (; i != i_end; ++i)
00088 for (unsigned j (0); j < i->size(); j += sz) {
00089 line = prf;
00090 line += std::string(*i, j, sz);
00091 handle_.write(line);
00092 }
00093 }
00094
00095 prefix_ void senf::log::SyslogUDPTarget::consoleFormat(std::ostream & os)
00096 {
00097 LogFormat::consoleFormat(os);
00098 os << "syslog prefix " << (syslogFormat_ ? "enabled" : "disabled") << "\n";
00099 }
00100
00101 namespace senf {
00102 namespace log {
00103
00104 SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogUDPTarget, LogFacility,
00105 (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG)
00106 (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5)
00107 (LOCAL6)(LOCAL7));
00108
00109 }}
00110
00111 prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole()
00112 {
00113 namespace kw = console::kw;
00114 namespace fty = console::factory;
00115
00116 detail::TargetRegistry::instance().consoleDir()
00117 .add("udp-target",
00118 fty::Command<console::DirectoryNode::ptr (*)(INet4SocketAddress const &,
00119 LogFacility)
00120 >(&RegisterConsole::create)
00121 .arg("address", "target address to send log messages to")
00122 .arg("facility", "syslog facility to send messages to. One of\n"
00123 " AUTHPRIV CRON DAEMON FTP KERN LPR MAIL NEWS SYSLOG USER\n"
00124 " UUCP LOCAL0 LOCAL1 LOCAL2 LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7",
00125 kw::default_value = USER)
00126 .doc("Create new udp target. The {address} can be an IPv4 or IPv6 address. If the port\n"
00127 "number is omitted, it defaults to the default syslog port 514. Examples:\n"
00128 "\n"
00129 "Create new udp target sending messages to the syslog daemon running at localhost\n"
00130 " $ udp-target localhost\n"
00131 " <Directory '/sys/log/udp-127.0.0.1:514'>\n"
00132 "\n"
00133 "In a configuration file, create new udp target and set some parameters (If\n"
00134 "written on one line, this works at the console too:\n"
00135 " /sys/log/udp-target localhost:2345 LOCAL2 {\n"
00136 " route (IMPORTANT); # route all important messages\n"
00137 " timeFormat \"\"; # use non-formatted time format\n"
00138 " showArea false; # don't show log area\n"
00139 " syslog false; # no syslog format, just plain udp\n"
00140 " }\n") );
00141 detail::TargetRegistry::instance().consoleDir()
00142 .add("udp-target",
00143 fty::Command<console::DirectoryNode::ptr (*)(INet4Address const &, LogFacility)
00144 >(&RegisterConsole::create)
00145 .arg("address")
00146 .arg("facility", kw::default_value = USER) );
00147 detail::TargetRegistry::instance().consoleDir()
00148 .add("udp-target",
00149 fty::Command<console::DirectoryNode::ptr (*)(INet6SocketAddress const &, LogFacility)
00150 >(&RegisterConsole::create)
00151 .arg("address")
00152 .arg("facility", kw::default_value = USER) );
00153 detail::TargetRegistry::instance().consoleDir()
00154 .add("udp-target",
00155 fty::Command<console::DirectoryNode::ptr (*)(INet6Address const &, LogFacility)
00156 >(&RegisterConsole::create)
00157 .arg("address")
00158 .arg("facility", kw::default_value = USER) );
00159 }
00160
00161 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
00162 senf::log::SyslogUDPTarget::RegisterConsole::create(INet4SocketAddress const & target,
00163 LogFacility facility)
00164 {
00165 std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility));
00166 Target & tg (*tp.get());
00167 detail::TargetRegistry::instance().dynamicTarget(tp);
00168 return tg.consoleDir().node().thisptr();
00169 }
00170
00171 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
00172 senf::log::SyslogUDPTarget::RegisterConsole::create(INet4Address const & target,
00173 LogFacility facility)
00174 {
00175 std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility));
00176 Target & tg (*tp.get());
00177 detail::TargetRegistry::instance().dynamicTarget(tp);
00178 return tg.consoleDir().node().thisptr();
00179 }
00180
00181 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
00182 senf::log::SyslogUDPTarget::RegisterConsole::create(INet6SocketAddress const & target,
00183 LogFacility facility)
00184 {
00185 std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility));
00186 Target & tg (*tp.get());
00187 detail::TargetRegistry::instance().dynamicTarget(tp);
00188 return tg.consoleDir().node().thisptr();
00189 }
00190
00191 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
00192 senf::log::SyslogUDPTarget::RegisterConsole::create(INet6Address const & target,
00193 LogFacility facility)
00194 {
00195 std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility));
00196 Target & tg (*tp.get());
00197 detail::TargetRegistry::instance().dynamicTarget(tp);
00198 return tg.consoleDir().node().thisptr();
00199 }
00200
00201
00202 #undef prefix_
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214