7 #if defined(LOG4CPP_HAVE_BOOST) 8 #include <boost/version.hpp> 9 #if BOOST_VERSION >= 103500 11 #define LOG4CPP_HAVE_INT64_T 15 #include <boost/asio/ip/tcp.hpp> 16 #include <boost/thread/mutex.hpp> 17 #include <boost/thread/once.hpp> 18 #include <boost/thread/condition.hpp> 19 #include <boost/thread/thread.hpp> 20 #include <boost/noncopyable.hpp> 25 void sender_shutdown();
27 struct SmptAppender::mail_params
29 mail_params(
const std::string& host,
30 const std::string& from,
31 const std::string& to,
32 const std::string& subject) : host_(host), from_(from), to_(to), subject_(subject)
44 struct sender :
public boost::noncopyable
47 static sender& instance();
49 static sender* instance_;
50 void send(
const SmptAppender::mail_params& mp,
const LoggingEvent& event);
52 typedef std::list<std::pair<SmptAppender::mail_params, LoggingEvent> > mails_t;
54 boost::mutex mails_mutex_;
55 boost::condition data_condition_;
57 std::auto_ptr<boost::thread> sender_thread_;
58 volatile bool should_exit_;
61 sender* sender::instance_ = 0;
62 boost::once_flag sender_once = BOOST_ONCE_INIT;
64 sender::sender() : should_exit_(false)
66 sender_thread_.reset(
new boost::thread(boost::ref(*
this)));
72 sender::instance_ =
new sender;
75 sender& sender::instance()
77 boost::call_once(&create_sender, sender_once);
81 void sender::shutdown()
83 {boost::mutex::scoped_lock lk(mails_mutex_);
85 data_condition_.notify_all();
88 sender_thread_->join();
92 void sender::send(
const SmptAppender::mail_params& mp,
const LoggingEvent& event)
94 boost::mutex::scoped_lock lk(mails_mutex_);
95 mails_.push_back(mails_t::value_type(mp, event));
96 data_condition_.notify_all();
99 void sender::operator()()
105 {boost::mutex::scoped_lock lk(mails_mutex_);
106 if (should_exit_ && mails_.empty())
111 data_condition_.wait(lk);
112 if (should_exit_ && mails_.empty())
121 boost::asio::ip::tcp::iostream s;
122 s.exceptions(std::ios::failbit | std::ios::eofbit | std::ios::badbit);
123 s.connect(i->first.host_,
"25");
125 std::getline(s, buf);
126 s <<
"HELO test\xd\xa" << std::flush;
127 std::getline(s, buf);
128 s <<
"MAIL FROM:" << i->first.from_<<
"\xd\xa" << std::flush;
129 std::getline(s, buf);
130 s <<
"RCPT TO:" << i->first.to_ <<
"\xd\xa" << std::flush;
131 std::getline(s, buf);
132 s <<
"DATA\xd\xa" << std::flush;
133 std::getline(s, buf);
134 s <<
"Subject: " << i->first.subject_ <<
"\xd\xa""Content-Transfer-Encoding: 8bit\xd\xa\xd\xa" 135 << i->second.message <<
"\xd\xa" ".\xd\xa" << std::flush;
136 std::getline(s, buf);
137 s <<
"QUIT\xd\xa" << std::flush;
138 std::getline(s, buf);
140 catch(
const std::exception& e)
142 std::cout << e.what();
145 {boost::mutex::scoped_lock lk(mails_mutex_);
152 void sender_shutdown()
154 sender::instance().shutdown();
157 SmptAppender::SmptAppender(
const std::string& name,
158 const std::string& host,
159 const std::string& from,
160 const std::string& to,
161 const std::string& subject) : LayoutAppender(name),
162 mail_params_(new mail_params(host, from, to, subject))
167 void SmptAppender::_append(
const LoggingEvent& event)
169 sender::instance().send(*mail_params_, event);
172 SmptAppender::~SmptAppender()
179 std::string name, host, from, to, subject;
180 params.get_for(
"SMTP appender").required(
"name", name)(
"host", host)(
"from", from)
181 (
"to", to)(
"subject", subject);
182 return std::auto_ptr<Appender>(
new SmptAppender(name, host, from, to, subject));
185 #endif // BOOST_VERSION >= 103500 186 #endif // LOG4CPP_HAS_BOOST
std::auto_ptr< Appender > create_smtp_appender(const FactoryParams &)
static HierarchyMaintainer & getDefaultMaintainer()
void register_shutdown_handler(shutdown_fun_ptr handler)