SmtpAppender.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2002, Log4cpp Project. All rights reserved.
3  *
4  * See the COPYING file for the terms of usage and distribution.
5  */
6 
7 #if defined(LOG4CPP_HAVE_BOOST)
8 #include <boost/version.hpp>
9 #if BOOST_VERSION >= 103500
10 
11 #define LOG4CPP_HAVE_INT64_T
12 #include <log4cpp/SmtpAppender.hh>
13 #include <log4cpp/FactoryParams.hh>
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>
21 #include <memory>
22 
23 namespace log4cpp
24 {
25  void sender_shutdown();
26 
27  struct SmptAppender::mail_params
28  {
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)
33  {
34  }
35 
36  std::string host_;
37  std::string from_;
38  std::string to_;
39  std::string subject_;
40  };
41 
42  namespace
43  {
44  struct sender : public boost::noncopyable
45  {
46  sender();
47  static sender& instance();
48  void shutdown();
49  static sender* instance_;
50  void send(const SmptAppender::mail_params& mp, const LoggingEvent& event);
51  void operator()();
52  typedef std::list<std::pair<SmptAppender::mail_params, LoggingEvent> > mails_t;
53 
54  boost::mutex mails_mutex_;
55  boost::condition data_condition_;
56  mails_t mails_;
57  std::auto_ptr<boost::thread> sender_thread_;
58  volatile bool should_exit_;
59  };
60 
61  sender* sender::instance_ = 0;
62  boost::once_flag sender_once = BOOST_ONCE_INIT;
63 
64  sender::sender() : should_exit_(false)
65  {
66  sender_thread_.reset(new boost::thread(boost::ref(*this)));
68  }
69 
70  void create_sender()
71  {
72  sender::instance_ = new sender;
73  }
74 
75  sender& sender::instance()
76  {
77  boost::call_once(&create_sender, sender_once);
78  return *instance_;
79  }
80 
81  void sender::shutdown()
82  {
83  {boost::mutex::scoped_lock lk(mails_mutex_);
84  should_exit_ = true;
85  data_condition_.notify_all();
86  }
87 
88  sender_thread_->join();
89  delete instance_;
90  }
91 
92  void sender::send(const SmptAppender::mail_params& mp, const LoggingEvent& event)
93  {
94  boost::mutex::scoped_lock lk(mails_mutex_);
95  mails_.push_back(mails_t::value_type(mp, event));
96  data_condition_.notify_all();
97  }
98 
99  void sender::operator()()
100  {
101  while(!should_exit_)
102  {
103  mails_t::iterator i;
104 
105  {boost::mutex::scoped_lock lk(mails_mutex_);
106  if (should_exit_ && mails_.empty())
107  return;
108 
109  if (mails_.empty())
110  {
111  data_condition_.wait(lk);
112  if (should_exit_ && mails_.empty())
113  return;
114  }
115 
116  i = mails_.begin();
117  }
118 
119  try
120  {
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");
124  std::string buf;
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);
139  }
140  catch(const std::exception& e)
141  {
142  std::cout << e.what();
143  }
144 
145  {boost::mutex::scoped_lock lk(mails_mutex_);
146  mails_.erase(i);
147  }
148  }
149  }
150  }
151 
152  void sender_shutdown()
153  {
154  sender::instance().shutdown();
155  }
156 
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))
163 
164  {
165  }
166 
167  void SmptAppender::_append(const LoggingEvent& event)
168  {
169  sender::instance().send(*mail_params_, event);
170  }
171 
172  SmptAppender::~SmptAppender()
173  {
174  delete mail_params_;
175  }
176 
177  std::auto_ptr<Appender> create_smtp_appender(const FactoryParams& params)
178  {
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));
183  }
184 }
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)


log4cpp
Author(s): Stephen Roderick, Bastiaan Bakker, Cedric Le Goater, Steve Ostlind, Marcel Harkema, Walter Stroebel, Glenn Scott and Tony Cheung
autogenerated on Sun Jun 23 2019 19:14:17