00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "FileTarget.hh"
00027
00028
00029
00030 #include <senf/Utils/Console/ParsedCommand.hh>
00031 #include <senf/Utils/Console/Variables.hh>
00032 #include <senf/Utils/Console/ScopedDirectory.hh>
00033 #include <boost/filesystem/path.hpp>
00034
00035
00036 #define prefix_
00037
00038
00039 namespace {
00040
00041 std::string getNodename(std::string const & filename, std::string const & nodename)
00042 {
00043 if (! nodename.empty())
00044 return nodename;
00045 return boost::filesystem::path(filename).leaf();
00046 }
00047
00048 }
00049
00050 prefix_ senf::log::FileTarget::FileTarget(std::string const & filename,
00051 std::string const & nodename)
00052 : ofstream_t (filename.c_str(), std::ofstream::app),
00053 IOStreamTarget (getNodename(filename, nodename), ofstream_t::member),
00054 file_ (filename)
00055 {
00056 namespace fty = console::factory;
00057
00058 if (! ofstream_t::member)
00059 SENF_THROW_SYSTEM_EXCEPTION("logfile open") << ": " << filename;
00060 consoleDir()
00061 .add( "reopen",
00062 fty::Command(SENF_MEMBINDFNP(void, FileTarget, reopen, ()))
00063 .doc("Reopen logfile") );
00064 consoleDir()
00065 .add("reopen",
00066 fty::Command(SENF_MEMBINDFNP(void, FileTarget, reopen, (std::string const &)))
00067 .arg("filename","new filename")
00068 .overloadDoc("Reopen logfile under new name") );
00069 consoleDir()
00070 .add("file", fty::Variable(boost::cref(file_))
00071 .doc("Show filename log messages are sent to") );
00072 }
00073
00074 prefix_ void senf::log::FileTarget::reopen()
00075 {
00076 ofstream_t::member.close();
00077 ofstream_t::member.open(file_.c_str(), std::ofstream::app);
00078 }
00079
00080 prefix_ void senf::log::FileTarget::reopen(std::string const & file)
00081 {
00082 file_ = file;
00083 reopen();
00084
00085 console::DirectoryNode::ptr parent (consoleDir().node().parent());
00086 if (parent)
00087 parent->add(file, consoleDir().node().unlink());
00088 }
00089
00090 prefix_ std::string const & senf::log::FileTarget::filename()
00091 const
00092 {
00093 return file_;
00094 }
00095
00096 prefix_ senf::log::FileTarget::RegisterConsole::RegisterConsole()
00097 {
00098 namespace kw = console::kw;
00099 namespace fty = console::factory;
00100
00101 detail::TargetRegistry::instance().consoleDir()
00102 .add("file-target", fty::Command(&RegisterConsole::create)
00103 .arg("filename", "name of logfile")
00104 .arg("nodename", "name of node in console. Defaults to the files basename",
00105 kw::default_value = "")
00106 .doc("Create new file target. Examples:\n"
00107 "\n"
00108 "Create new file target '/var/log/example.log\n"
00109 " $ file-target \"/var/log/example.log\"\n"
00110 " <Directory '/sys/log/example.log'>\n"
00111 "\n"
00112 "In a configuration file, create new file target '/var/log/example.log' and set\n"
00113 "some parameters (If written on one line, this works at the console too:\n"
00114 " /sys/log/file-target \"/var/log/example.log\" mainlog {\n"
00115 " route (IMPORTANT); # route all important messages\n"
00116 " timeFormat \"\"; # use non-formatted time format\n"
00117 " showArea false; # don't show log area\n"
00118 " }\n") );
00119 }
00120
00121 prefix_ boost::shared_ptr<senf::console::DirectoryNode>
00122 senf::log::FileTarget::RegisterConsole::create(std::string const & filename,
00123 std::string const & nodename)
00124 {
00125 std::auto_ptr<Target> tp (new FileTarget(filename, nodename));
00126 Target & target (*tp.get());
00127 detail::TargetRegistry::instance().dynamicTarget(tp);
00128 return target.consoleDir().node().thisptr();
00129 }
00130
00131
00132 #undef prefix_
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144