SyslogUDPTarget.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "SyslogUDPTarget.hh"
18 //#include "SyslogUDPTarget.ih"
19 
20 // Custom includes
21 #include <sstream>
22 #include <boost/algorithm/string/trim.hpp>
23 #include <boost/tokenizer.hpp>
27 #include "SyslogTarget.hh"
28 
29 //#include "SyslogUDPTarget.mpp"
30 #define prefix_
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 prefix_ void senf::log::SyslogUDPTarget::init()
34 {
35  namespace kw = console::kw;
36  namespace fty = console::factory;
37 
38  consoleDir().remove("format");
39  consoleDir()
40  .add("format", fty::Command(&SyslogUDPTarget::consoleFormat, this)
41  .doc("Show the current log message format.") );
42  consoleDir()
43  .add("syslog", fty::Command(SENF_MEMBINDFNP(void, SyslogUDPTarget, syslog, (bool)))
44  .arg("flag","new syslog format state",
45  kw::default_value=true)
46  .doc("Change the syslog format flag. By default, syslog formating is enabled. In this\n"
47  "state, the udp target will send out minimal but valid syslog format messages.\n"
48  "\n"
49  "Disabling syslog format will remove the syslog prefix. Log messages will then be\n"
50  "sent using plain UDP.") );
51 }
52 
53 prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream,
54  std::string const & area, unsigned level,
55  std::string const & message)
56 {
57  std::string m (message);
58  boost::trim_right(m);
60 
61  std::stringstream prfstream;
62  // The space after the '>' is there on purpose: It ensures, that the prefix (which may be empty)
63  // or message will not inadvertently be interpreted as date or hostname by a receiving syslog
64  // daemon or proxy
65  if (syslogFormat_)
66  prfstream << '<' << (facility_ | SyslogTarget::LEVELMAP[level]) << "> ";
67  prfstream << prefix(timestamp, stream, area, level);
68  std::string const & prf (prfstream.str());
69 
70  typedef boost::char_separator<char> Separator;
71  typedef boost::tokenizer<Separator> Tokenizer;
72  Separator separator ("\n");
73  Tokenizer tokenizer (m, separator);
74  Tokenizer::iterator i (tokenizer.begin());
75  Tokenizer::iterator const i_end (tokenizer.end());
76 
77  std::string line;
78  unsigned sz (896-prf.size());
79  for (; i != i_end; ++i)
80  for (unsigned j (0); j < i->size(); j += sz) {
81  line = prf;
82  line += std::string(*i, j, sz);
83  try {
84  handle_.write(line);
85  }
86  catch(...) {
87  // ignore write/send errors
88  }
89  }
90 }
91 
92 prefix_ void senf::log::SyslogUDPTarget::consoleFormat(std::ostream & os)
93 {
94  LogFormat::consoleFormat(os);
95  os << "syslog prefix " << (syslogFormat_ ? "enabled" : "disabled") << "\n";
96 }
97 
98 namespace senf {
99 namespace log {
100 
104  (LOCAL6)(LOCAL7));
105 
106 }}
107 
108 prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole()
109 {
110  namespace kw = console::kw;
111  namespace fty = console::factory;
112 
113  detail::TargetRegistry::instance().consoleDir()
114  .add("udp-target",
115  fty::Command<console::DirectoryNode::ptr (*)(INet4SocketAddress const &,
116  LogFacility)
117  >(&RegisterConsole::create)
118  .arg("address", "target address to send log messages to")
119  .arg("facility", "syslog facility to send messages to. One of\n"
120  " AUTHPRIV CRON DAEMON FTP KERN LPR MAIL NEWS SYSLOG USER\n"
121  " UUCP LOCAL0 LOCAL1 LOCAL2 LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7",
122  kw::default_value = USER)
123  .doc("Create new udp target. The {address} can be an IPv4 or IPv6 address. If the port\n"
124  "number is omitted, it defaults to the default syslog port 514. Examples:\n"
125  "\n"
126  "Create new udp target sending messages to the syslog daemon running at localhost\n"
127  " $ udp-target localhost\n"
128  " <Directory '/sys/log/udp-127.0.0.1:514'>\n"
129  "\n"
130  "In a configuration file, create new udp target and set some parameters (If\n"
131  "written on one line, this works at the console too:\n"
132  " /sys/log/udp-target localhost:2345 LOCAL2 {\n"
133  " route (IMPORTANT); # route all important messages\n"
134  " timeFormat \"\"; # use non-formatted time format\n"
135  " showArea false; # don't show log area\n"
136  " syslog false; # no syslog format, just plain udp\n"
137  " }\n") );
138  detail::TargetRegistry::instance().consoleDir()
139  .add("udp-target",
140  fty::Command<console::DirectoryNode::ptr (*)(INet4Address const &, LogFacility)
141  >(&RegisterConsole::create)
142  .arg("address")
143  .arg("facility", kw::default_value = USER) );
144  detail::TargetRegistry::instance().consoleDir()
145  .add("udp-target",
146  fty::Command<console::DirectoryNode::ptr (*)(INet6SocketAddress const &, LogFacility)
147  >(&RegisterConsole::create)
148  .arg("address")
149  .arg("facility", kw::default_value = USER) );
150  detail::TargetRegistry::instance().consoleDir()
151  .add("udp-target",
152  fty::Command<console::DirectoryNode::ptr (*)(INet6Address const &, LogFacility)
153  >(&RegisterConsole::create)
154  .arg("address")
155  .arg("facility", kw::default_value = USER) );
156 }
157 
158 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
159 senf::log::SyslogUDPTarget::RegisterConsole::create(INet4SocketAddress const & target,
160  LogFacility facility)
161 {
162  std::unique_ptr<Target> tp (new SyslogUDPTarget(target, facility));
163  Target & tg (*tp.get());
164  detail::TargetRegistry::instance().dynamicTarget(std::move(tp));
165  return tg.consoleDir().node().thisptr();
166 }
167 
168 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
169 senf::log::SyslogUDPTarget::RegisterConsole::create(INet4Address const & target,
170  LogFacility facility)
171 {
172  std::unique_ptr<Target> tp (new SyslogUDPTarget(target, facility));
173  Target & tg (*tp.get());
174  detail::TargetRegistry::instance().dynamicTarget(std::move(tp));
175  return tg.consoleDir().node().thisptr();
176 }
177 
178 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
179 senf::log::SyslogUDPTarget::RegisterConsole::create(INet6SocketAddress const & target,
180  LogFacility facility)
181 {
182  std::unique_ptr<Target> tp (new SyslogUDPTarget(target, facility));
183  Target & tg (*tp.get());
184  detail::TargetRegistry::instance().dynamicTarget(std::move(tp));
185  return tg.consoleDir().node().thisptr();
186 }
187 
188 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
189 senf::log::SyslogUDPTarget::RegisterConsole::create(INet6Address const & target,
190  LogFacility facility)
191 {
192  std::unique_ptr<Target> tp (new SyslogUDPTarget(target, facility));
193  Target & tg (*tp.get());
194  detail::TargetRegistry::instance().dynamicTarget(std::move(tp));
195  return tg.consoleDir().node().thisptr();
196 }
197 
198 //-/////////////////////////////////////////////////////////////////////////////////////////////////
199 #undef prefix_
200 //#include "SyslogUDPTarget.mpp"
201 
202 
203 // Local Variables:
204 // mode: c++
205 // fill-column: 100
206 // comment-column: 40
207 // c-file-style: "senf"
208 // indent-tabs-mode: nil
209 // ispell-local-dictionary: "american"
210 // compile-command: "scons -u test"
211 // End:
#define SENF_MEMBINDFNP(ret, cls, fn, args)
static int const LEVELMAP[8]
Definition: SyslogTarget.hh:89
bool syslog() const
true, if using syslog format, false otherwise
boost::shared_ptr< DirectoryNode > ptr
void quoteNonPrintable(std::string &s)
Definition: LogFormat.cc:140
SyslogTarget public header.
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))
senf::console::ScopedDirectory & consoleDir()
Get console/config directory.
Definition: Target.cc:212
GenericNode::ptr remove(std::string const &name)
#define prefix_
std::string prefix(time_type timestamp, std::string const &stream, std::string const &area, unsigned level)
Definition: LogFormat.cc:108
config::time_type time_type
Definition: TimeSource.hh:31
boost::range_const_iterator< ForwardReadableRange const >::type write(ForwardReadableRange const &range)
SyslogUDPTarget(INet4Address const &target, int facility=LOG_USER)
SyslogUDPTarget public header.
Target(std::string const &name)
Definition: Target.cc:45
NodeType & add(std::string const &name, boost::shared_ptr< NodeType > node)