return os;
}
+prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
+{
+ std::string s;
+ if (!(is >> s))
+ return is;
+ try {
+ addr = INet4Address::from_string(s);
+ }
+ catch (AddressException &) {
+ is.setstate(std::ios::failbit);
+ }
+ return is;
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "INet4Address.mpp"
\related INet4Address
*/
std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
+ std::istream & operator>>(std::istream & os, INet4Address & addr);
/** \brief CHeck INet4Address against a fixed network prefix
return os;
}
+prefix_ std::istream & senf::operator>>(std::istream & is, INet6Address & addr)
+{
+ std::string s;
+ if (!(is >> s))
+ return is;
+ try {
+ addr = INet6Address::from_string(s);
+ }
+ catch (AddressException &) {
+ is.setstate(std::ios::failbit);
+ }
+ return is;
+}
senf::INet6Address const senf::INet6Address::None;
senf::INet6Address const senf::INet6Address::Loopback (0u,0u,0u,0u,0u,0u,0u,1u);
\related INet6Address
*/
std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
+ std::istream & operator>>(std::istream & is, INet6Address & addr);
/** \brief Check INet6Address against a fixed network prefix
port(p);
}
+prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
+{
+ os << addr.address() << ":" << addr.port();
+ return os;
+}
+
+prefix_ std::istream & senf::operator>>(std::istream & is, INet4SocketAddress & addr)
+{
+ std::string s;
+ if (!(is >> s))
+ return is;
+ try {
+ addr = INet4SocketAddress(s);
+ }
+ catch (AddressException &) {
+ is.setstate(std::ios::failbit);
+ }
+ return is;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::INet6SocketAddress
}
}
+prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr)
+{
+ os << '[' << addr.address();
+ std::string iface (addr.iface());
+ if (! iface.empty())
+ os << '%' << iface;
+ os << "]:" << addr.port();
+ return os;
+}
+
+prefix_ std::istream & senf::operator>>(std::istream & is, INet6SocketAddress & addr)
+{
+ std::string s;
+ if (!(is >> s))
+ return is;
+ try {
+ addr = INet6SocketAddress(s);
+ }
+ catch (AddressException &) {
+ is.setstate(std::ios::failbit);
+ }
+ return is;
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "INetAddressing.mpp"
addr_.sin_port = htons(p);
}
-prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
-{
- os << addr.address() << ":" << addr.port();
- return os;
-}
-
///////////////////////////////////////////////////////////////////////////
// senf::INet6SocketAddress
assignIface(iface);
}
-prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr)
-{
- os << '[' << addr.address();
- std::string iface (addr.iface());
- if (! iface.empty())
- os << '%' << iface;
- os << "]:" << addr.port();
- return os;
-}
-
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
\related INet4SocketAddress
*/
std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
+ std::istream & operator>>(std::istream & is, INet4SocketAddress & addr);
/** \brief IPv6 socket address
\related INet6SocketAddress
*/
std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
+ std::istream & operator>>(std::istream & is, INet6SocketAddress & addr);
/// \addtogroup policy_impl_group
/// @{
{
if (skipping())
return "";
+ (void) cwd(); // ensure, cwd is live.
return "/" + senf::stringJoin(
senf::make_transform_range(
boost::make_iterator_range(boost::next(cwd_.begin()), cwd_.end()),
//#include "FileTarget.ih"
// Custom includes
+#include "../Console/Console.hh"
//#include "FileTarget.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-prefix_ senf::log::FileTarget::FileTarget(std::string file)
+prefix_ senf::log::FileTarget::FileTarget(std::string const & file)
: ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member),
file_(file)
-{}
+{
+ consoleDir().add( "reopen", senf::membind(
+ static_cast<void (FileTarget::*)()>(&FileTarget::reopen),
+ this))
+ .doc("Reopen logfile");
+ consoleDir().add("reopen", senf::membind(
+ static_cast<void (FileTarget::*)(std::string const &)>(&FileTarget::reopen),
+ this))
+ .arg("filename","new filename")
+ .overloadDoc("Reopen logfile under new name");
+}
prefix_ void senf::log::FileTarget::reopen()
{
ofstream_t::member.open(file_.c_str(), std::ofstream::app);
}
-prefix_ void senf::log::FileTarget::reopen(std::string file)
+prefix_ void senf::log::FileTarget::reopen(std::string const & file)
{
file_ = file;
reopen();
+ // Rename console directory
+ console::DirectoryNode::ptr parent (consoleDir().node().parent());
+ if (parent)
+ parent->add(file, consoleDir().node().unlink());
+}
+
+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.");
+}
+
+prefix_ void senf::log::FileTarget::RegisterConsole::create(std::string const & filename)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new FileTarget(filename)));
}
///////////////////////////////cc.e////////////////////////////////////////
///\name Structors and default members
///@{
- explicit FileTarget(std::string file); ///< Construct FileTarget writing to \a file
+ explicit FileTarget(std::string const & filename);
+ ///< Construct FileTarget writing to \a file
///@}
///////////////////////////////////////////////////////////////////////////
void reopen(); ///< Reopen %log after log-file rotation
- void reopen(std::string file); ///< Reopen %log under a new name
+ void reopen(std::string const & file); ///< Reopen %log under a new name
private:
std::string file_;
+
+ struct RegisterConsole {
+ RegisterConsole();
+ static void create(std::string const & filename);
+ static RegisterConsole instance;
+ };
};
}}
//#include "SyslogTarget.ih"
// Custom includes
+#include "../Console/Console.hh"
//#include "SyslogTarget.mpp"
#define prefix_
syslog(facility_ | LEVELMAP[level], "%s", message.c_str());
}
+namespace senf {
+namespace log {
+
+ 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));
+
+}}
+
+prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole()
+{
+ namespace kw = senf::console::kw;
+
+ 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",
+ kw::default_value = USER)
+ .doc("Create new syslog target.");
+}
+
+prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new SyslogTarget(facility)));
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "SyslogTarget.mpp"
public:
static int const LEVELMAP[8];
+
+ enum LogFacility {
+ AUTHPRIV = LOG_AUTHPRIV,
+ CRON = LOG_CRON,
+ DAEMON = LOG_DAEMON,
+ FTP = LOG_FTP,
+ KERN = LOG_KERN,
+ LOCAL0 = LOG_LOCAL0,
+ LOCAL1 = LOG_LOCAL1,
+ LOCAL2 = LOG_LOCAL2,
+ LOCAL3 = LOG_LOCAL3,
+ LOCAL4 = LOG_LOCAL4,
+ LOCAL5 = LOG_LOCAL5,
+ LOCAL6 = LOG_LOCAL6,
+ LOCAL7 = LOG_LOCAL7,
+ LPR = LOG_LPR,
+ MAIL = LOG_MAIL,
+ NEWS = LOG_NEWS,
+ SYSLOG = LOG_SYSLOG,
+ USER = LOG_USER,
+ UUCP = LOG_UUCP
+ };
+
+ private:
+ struct RegisterConsole {
+ RegisterConsole();
+ static void create(LogFacility facility);
+ static RegisterConsole instance;
+ };
};
}}
#include <sstream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
+#include "../Console/Console.hh"
//#include "SyslogUDPTarget.mpp"
#define prefix_
}
}
+namespace senf {
+namespace log {
+
+ SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogUDPTarget, LogFacility,
+ (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG)
+ (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5)
+ (LOCAL6)(LOCAL7));
+
+}}
+
+prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole()
+{
+ namespace kw = senf::console::kw;
+
+ detail::TargetRegistry::instance().consoleDir().add(
+ "udp-target", static_cast<void (*)(INet4SocketAddress const &, LogFacility)>(
+ &RegisterConsole::create))
+ .arg("address", "target address to send log messages to")
+ .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",
+ 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.");
+ detail::TargetRegistry::instance().consoleDir().add(
+ "udp-target", static_cast<void (*)(INet4Address const &, LogFacility)>(
+ &RegisterConsole::create))
+ .arg("address")
+ .arg("facility", kw::default_value = USER);
+ detail::TargetRegistry::instance().consoleDir().add(
+ "udp-target", static_cast<void (*)(INet6SocketAddress const &, LogFacility)>(
+ &RegisterConsole::create))
+ .arg("address")
+ .arg("facility", kw::default_value = USER);
+ detail::TargetRegistry::instance().consoleDir().add(
+ "udp-target", static_cast<void (*)(INet6Address const &, LogFacility)>(
+ &RegisterConsole::create))
+ .arg("address")
+ .arg("facility", kw::default_value = USER);
+}
+
+prefix_ void
+senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target,
+ LogFacility facility)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+}
+
+prefix_ void
+senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target,
+ LogFacility facility)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+}
+
+prefix_ void
+senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target,
+ LogFacility facility)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+}
+
+prefix_ void
+senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target,
+ LogFacility facility)
+{
+ detail::TargetRegistry::instance().dynamicTarget(
+ std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "SyslogUDPTarget.mpp"
include the \c PRI part but skip the \c HEADER part (which includes the timestamp and
hostname) for better performance. We add a space after the \c PRI to force the syslog
daemon to skip the \c HEADER part.
+
+ \ingroup targets
*/
class SyslogUDPTarget
: public Target, private detail::LogFormat
senf::ConnectedCommunicationPolicy,
senf::WriteablePolicy>::policy > Handle;
Handle handle_;
+
+ public:
+ enum LogFacility {
+ AUTHPRIV = LOG_AUTHPRIV,
+ CRON = LOG_CRON,
+ DAEMON = LOG_DAEMON,
+ FTP = LOG_FTP,
+ KERN = LOG_KERN,
+ LOCAL0 = LOG_LOCAL0,
+ LOCAL1 = LOG_LOCAL1,
+ LOCAL2 = LOG_LOCAL2,
+ LOCAL3 = LOG_LOCAL3,
+ LOCAL4 = LOG_LOCAL4,
+ LOCAL5 = LOG_LOCAL5,
+ LOCAL6 = LOG_LOCAL6,
+ LOCAL7 = LOG_LOCAL7,
+ LPR = LOG_LPR,
+ MAIL = LOG_MAIL,
+ NEWS = LOG_NEWS,
+ SYSLOG = LOG_SYSLOG,
+ USER = LOG_USER,
+ UUCP = LOG_UUCP
+ };
+
+ private:
+
+ struct RegisterConsole {
+ RegisterConsole();
+ static void create(senf::INet4SocketAddress const & target,
+ LogFacility facility = USER);
+ static void create(senf::INet4Address const & target,
+ LogFacility facility = USER);
+ static void create(senf::INet6SocketAddress const & target,
+ LogFacility facility = USER);
+ static void create(senf::INet6Address const & target,
+ LogFacility facility = USER);
+ static RegisterConsole instance;
+ };
};
}}
kw::default_value = "senf::log::Debug")
.arg("area","area to write message to",
kw::default_value = "senf::log::DefaultArea")
- .arg("level", "log level",
+ .arg("level", "log level, one of:\n"
+ " VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL, FATAL",
kw::default_value = MESSAGE)
.arg("message", "message to write")
.doc("Write log message");
}
+prefix_ senf::log::detail::TargetRegistry::~TargetRegistry()
+{
+ Targets::iterator i (dynamicTargets_.begin());
+ Targets::iterator const i_end (dynamicTargets_.end());
+ for (; i != i_end; ++i)
+ delete *i;
+}
+
prefix_ void senf::log::detail::TargetRegistry::consoleAreas(std::ostream & os)
{
AreaRegistry::iterator i (AreaRegistry::instance().begin());
///////////////////////////////////////////////////////////////////////////
// senf::log::detail::TargetRegistry
+prefix_ void senf::log::detail::TargetRegistry::dynamicTarget(std::auto_ptr<Target> target)
+{
+ target->consoleDir().add("remove", boost::function<void ()>(
+ boost::bind(
+ &TargetRegistry::consoleRemoveTarget, this, target.get())))
+ .doc("Remove target.");
+ dynamicTargets_.insert(target.release());
+}
+
prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target,
std::string const & name)
{
else
area.write( TimeSource::now(), stream, level, msg );
}
+
+prefix_ void senf::log::detail::TargetRegistry::consoleRemoveTarget(Target * target)
+{
+ dynamicTargets_.erase(target);
+ delete target;
+}
+
///////////////////////////////////////////////////////////////////////////
// namespace members
return os;
}
+//////////////////////////////////////////////////////////////////////////
+// I need to put this here, otherwise the file target will not be registered
+// if it is not used ... :-(
+
+senf::log::FileTarget::RegisterConsole senf::log::FileTarget::RegisterConsole::instance;
+senf::log::SyslogTarget::RegisterConsole senf::log::SyslogTarget::RegisterConsole::instance;
+senf::log::SyslogUDPTarget::RegisterConsole senf::log::SyslogUDPTarget::RegisterConsole::instance;
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
return fallbackRouting_;
}
+prefix_ senf::console::ScopedDirectory<> & senf::log::detail::TargetRegistry::consoleDir()
+{
+ return consoleDir_();
+}
+
////////////////////////////////////////
// private members
void routed();
bool fallbackRouting();
+ senf::console::ScopedDirectory<> & consoleDir();
+
+ void dynamicTarget(std::auto_ptr<Target> target);
+
private:
TargetRegistry();
+ ~TargetRegistry();
void registerTarget(Target * target, std::string const & name);
void unregisterTarget(Target * target);
void consoleStreams(std::ostream & os);
void consoleWrite(std::string const & stream, std::string const & area, Level level,
std::string const & msg);
+ void consoleRemoveTarget(Target * target);
typedef std::set<Target *> Targets;
Targets targets_;
bool fallbackRouting_;
console::LazyDirectory consoleDir_;
+
+ Targets dynamicTargets_;
friend class senf::log::Target;
friend class senf::singleton<TargetRegistry>;
prefix_ void senf::term::LineEditor::pushHistory(std::string const & text)
{
if (! text.empty()
- && (historyPoint_ == history_.size() || history_[historyPoint_] != text)
&& (history_.empty() || history_.back() != text)) {
history_.push_back(text);
while (history_.size() > MAX_HISTORY_SIZE)