r7785 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r7784‎ | r7785 | r7786 >
Date:16:07, 20 March 2005
Author:kateturner
Status:old
Tags:
Comment:
support for logging to servmon via unix domain socket
Modified paths:
  • /trunk/servmon/SConstruct (modified) (history)
  • /trunk/servmon/include/smlog.hxx (modified) (history)
  • /trunk/servmon/include/smnet.hxx (modified) (history)
  • /trunk/servmon/include/smstdinc.hxx (modified) (history)
  • /trunk/servmon/servmon.cxx (modified) (history)
  • /trunk/servmon/smirc.cxx (modified) (history)
  • /trunk/servmon/smlog.cxx (modified) (history)
  • /trunk/servmon/smlogmsg.c (added) (history)
  • /trunk/servmon/smnet.cxx (modified) (history)

Diff [purge]

Index: trunk/servmon/smlog.cxx
@@ -2,10 +2,96 @@
33 #include "smstdinc.hxx"
44 #include "smlog.hxx"
55 #include "smirc.hxx"
 6+#include "smthr.hxx"
67
78 namespace smlog {
89
 10+namespace {
 11+ struct loglsnd : smthr::daemon {
 12+ loglsnd(void) {
 13+ }
 14+ void start(void) {
 15+ std::cerr << "starting log daemon\n";
 16+ smnet::lsnrp s (new smnet::lsnr(smnet::unix));
 17+ std::cerr << "created socket\n";
 18+ std::remove("/tmp/servmon.log");
 19+ s->node("/tmp/servmon.log");
 20+ std::cerr << "set node\n";
 21+ try {
 22+ s->lsn();
 23+ std::cerr << "listen\n";
 24+ } catch (smnet::sckterr& e) {
 25+ SMI(log)->logmsg(0, std::string("Listen failed for log socket: ") + e.what());
 26+ return;
 27+ }
 28+ std::cerr << "listened\n";
 29+ boost::function<void(smnet::scktp, int)> f =
 30+ boost::bind(&loglsnd::newc, this, _1, _2);
 31+ SMI(smnet::smpx)->add(f, static_pointer_cast<smnet::sckt>(s), smnet::smpx::srd);
 32+ std::cerr << "added callback\n";
 33+ }
 34+ void newc(smnet::scktp sckt_, int) {
 35+ smnet::lsnrp s = dynamic_pointer_cast<smnet::lsnr>(sckt_);
 36+ std::cerr << "new client\n";
 37+ try {
 38+ smnet::clntp c = s->wt_acc();
 39+ std::cerr << "accepted\n";
 40+ boost::function<void(smnet::scktp, int)> f =
 41+ boost::bind(&loglsnd::cdata, this, _1, _2);
 42+ SMI(smnet::smpx)->add(f, static_pointer_cast<smnet::sckt>(c), smnet::smpx::srd);
 43+ std::cerr << "added cb for client\n";
 44+ } catch (smnet::sckterr& e) {
 45+ SMI(log)->logmsg(0, std::string("Accept failed for log socket: ") + e.what());
 46+ std::cerr << "got an error\n";
 47+ }
 48+ }
 49+ void cdata(smnet::scktp s_, int) {
 50+ smnet::clntp c = dynamic_pointer_cast<smnet::clnt>(s_);
 51+ std::cerr << "got data for client\n";
 52+ std::vector<u_char> data;
 53+ std::string levs;
 54+ std::string msg;
 55+ try {
 56+ c->rd(data);
 57+ } catch (smnet::sckterr&) {
 58+ goto errout;
 59+ }
 60+ std::cerr << "read data\n";
 61+ msg.assign(data.begin(), data.end());
 62+ levs = smutl::car(msg);
 63+ if (levs.empty()) {
 64+ SMI(log)->logmsg(0, "Malformed log message from socket");
 65+ goto errout;
 66+ }
 67+ while (!msg.empty() and msg[0] == ' ')
 68+ msg.erase(msg.begin());
 69+ if (msg.empty()) {
 70+ SMI(log)->logmsg(0, "Malformed log message from socket");
 71+ goto errout;
 72+ }
 73+ int lev;
 74+ try {
 75+ lev = lexical_cast<int>(levs);
 76+ } catch (bad_lexical_cast&) {
 77+ goto errout;
 78+ }
 79+ if (lev < 0 || lev > 16)
 80+ goto errout;
 81+ SMI(log)->logmsg(lev, msg);
 82+ errout:
 83+ std::cerr << "removing socket";
 84+ SMI(smnet::smpx)->rm(c);
 85+ }
 86+ };
 87+} // anonymous namespace
 88+
989 void
 90+log::initialise(void)
 91+{
 92+ (new loglsnd)->run();
 93+}
 94+
 95+void
1096 log::logmsg(int irclvl, str message)
1197 {
1298 std::string fmt = b::io::str(b::format("%% %s -- %s") % timestamp() % message);
Index: trunk/servmon/include/smlog.hxx
@@ -16,6 +16,8 @@
1717
1818 class log : public smutl::singleton<log> {
1919 public:
 20+ void initialise(void);
 21+
2022 void logmsg(int ircvl, str message);
2123 void debug(dbg_t func, str message);
2224
Index: trunk/servmon/include/smstdinc.hxx
@@ -47,6 +47,7 @@
4848 #include <sys/socket.h>
4949 #include <sys/stat.h>
5050 #include <sys/utsname.h>
 51+#include <sys/un.h>
5152
5253 #include <arpa/inet.h>
5354
Index: trunk/servmon/include/smnet.hxx
@@ -12,6 +12,10 @@
1313
1414 namespace smnet {
1515
 16+static const int
 17+ internet = 1,
 18+ unix = 2;
 19+
1620 struct sckterr : public std::runtime_error {
1721 sckterr(void) : std::runtime_error(std::strerror(errno)), err(errno) {};
1822 sckterr(char const *s) : std::runtime_error(s), err(0) {}
@@ -32,7 +36,7 @@
3337
3438 class sckt {
3539 public:
36 - sckt(void);
 40+ sckt(int type = internet);
3741 virtual ~sckt(void);
3842
3943 /*
@@ -47,17 +51,21 @@
4852 friend class smpx;
4953
5054 protected:
51 - sockaddr_in sin;
 55+ sockaddr_storage sin;
5256 int s;
 57+ int type;
 58+ int len;
5359
54 - sckt(int, sockaddr_in const *, socklen_t);
 60+ sckt(int, int, sockaddr const *, socklen_t);
5561 };
5662
5763 typedef shared_ptr<sckt> scktp;
5864
5965 class clnt : public sckt {
6066 public:
61 - clnt(void) {};
 67+ clnt(int type = internet)
 68+ : sckt(type)
 69+ {}
6270
6371 bool connect(void);
6472
@@ -79,8 +87,8 @@
8088 private:
8189 friend class lsnr;
8290
83 - clnt(int s_, sockaddr_in const * sin_, socklen_t len_)
84 - : sckt(s_, sin_, len_)
 91+ clnt(int type, int s_, sockaddr const * sin_, socklen_t len_)
 92+ : sckt(type, s_, sin_, len_)
8593 {}
8694
8795 uint _need_data(void);
@@ -91,6 +99,9 @@
92100
93101 class lsnr : public sckt {
94102 public:
 103+ lsnr(int type = internet)
 104+ : sckt(type)
 105+ {}
95106 void lsn(void);
96107 shared_ptr<clnt> wt_acc(void);
97108 };
Index: trunk/servmon/smnet.cxx
@@ -4,36 +4,67 @@
55
66 namespace smnet {
77
8 -sckt::sckt(void)
 8+sckt::sckt(int type)
99 {
10 - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 10+ int ftype = type == internet ? AF_INET : AF_UNIX;
 11+ this->type = type;
 12+ if ((s = socket(ftype, SOCK_STREAM, 0)) < 0)
1113 throw sckterr();
12 - sin.sin_family = AF_INET;
13 - sin.sin_addr.s_addr = htonl(INADDR_ANY);
14 - sin.sin_port = 0;
 14+ std::cerr << "new default socket " << s << "\n";
 15+ if (type == internet) {
 16+ struct sockaddr_in *sa = (sockaddr_in *)&sin;
 17+ memset(sa, 0, sizeof *sa);
 18+ sa->sin_family = ftype;
 19+ sa->sin_addr.s_addr = htonl(INADDR_ANY);
 20+ sa->sin_port = 0;
 21+ len = sizeof(*sa);
 22+ } else {
 23+ struct sockaddr_un *sa = (sockaddr_un *)&sin;
 24+ memset(sa, 0, sizeof *sa);
 25+ sa->sun_family = ftype;
 26+ sa->sun_path[0] = '\0';
 27+ len = SUN_LEN(sa);
 28+ }
1529 }
1630
17 -sckt::sckt(int s_, sockaddr_in const *sin_, socklen_t len)
 31+sckt::sckt(int type_, int s_, sockaddr const *sin_, socklen_t len)
1832 {
 33+ std::cerr << "new socket from child " << s_ << "\n";
1934 std::memcpy(&sin, sin_, len);
 35+ type = type_;
2036 s = s_;
 37+ this->len = len;
2138 }
2239
2340 sckt::~sckt(void) {
 41+ std::cerr << "deleting socket " << s << "\n";
2442 close(s);
2543 }
2644
2745 void sckt::svc(std::string const& s) {
28 - sin.sin_port = htons(lexical_cast<int>(s));
 46+ if (type == internet) {
 47+ sockaddr_in *sa = (sockaddr_in *)&sin;
 48+ sa->sin_port = htons(lexical_cast<int>(s));
 49+ } else {
 50+ /* no-op for unix domain */
 51+ }
2952 }
3053
3154 void sckt::node(std::string const& host) {
32 - struct hostent *hptr;
33 - if ((hptr = gethostbyname(host.c_str())) == NULL)
34 - throw sckterr(hstrerror(h_errno));
35 - in_addr **pptr = (in_addr **) hptr->h_addr_list;
36 - memcpy(&sin.sin_addr, *pptr, sizeof(struct in_addr));
37 - // XXX: try other addresses
 55+ if (type == internet) {
 56+ sockaddr_in *sa = (sockaddr_in *)&sin;
 57+ struct hostent *hptr;
 58+ if ((hptr = gethostbyname(host.c_str())) == NULL)
 59+ throw sckterr(hstrerror(h_errno));
 60+ in_addr **pptr = (in_addr **) hptr->h_addr_list;
 61+ memcpy(&sa->sin_addr, *pptr, sizeof(struct in_addr));
 62+ // XXX: try other addresses
 63+ } else {
 64+ sockaddr_un *sa = (sockaddr_un *)&sin;
 65+ strncpy(sa->sun_path, host.c_str(), 107);
 66+ sa->sun_path[107] = '\0';
 67+ len = SUN_LEN(sa);
 68+ }
3869 }
3970
4071 void lsnr::lsn(void) {
@@ -41,26 +72,26 @@
4273 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
4374 one = fcntl(s, F_GETFL, 0);
4475 fcntl(s, F_SETFL, one | O_NONBLOCK);
45 - if (bind(s, (sockaddr *) &sin, sizeof(sin)) < 0)
 76+ if (bind(s, (sockaddr *)&sin, len) < 0)
4677 throw sckterr();
4778 if (listen(s, 5) < 0)
4879 throw sckterr();
4980 }
5081
5182 bool clnt::connect(void) {
52 - if ((::connect(s, (sockaddr *) &sin, sizeof(sin)) < 0) && errno != EWOULDBLOCK)
 83+ if ((::connect(s, (sockaddr *)&sin, len) < 0) && errno != EWOULDBLOCK)
5384 throw sckterr();
5485 return (errno == EWOULDBLOCK) ? false : true;
5586 }
5687
5788 shared_ptr<clnt>
5889 lsnr::wt_acc(void) {
59 - sockaddr_in caddr;
 90+ sockaddr_storage caddr;
6091 socklen_t clen = sizeof(caddr);
6192 int i;
62 - if ((i = accept(s, (struct sockaddr *) &caddr, &clen)) < 0)
 93+ if ((i = accept(s, (sockaddr *)&caddr, &clen)) < 0)
6394 throw sckterr();
64 - clnt *n = new clnt(i, &caddr, clen);
 95+ clnt *n = new clnt(type, i, (sockaddr *)&caddr, clen);
6596 return shared_ptr<clnt>(n);
6697 }
6798
Index: trunk/servmon/servmon.cxx
@@ -29,6 +29,7 @@
3030 SMI(smcfg::cfg); // force reading
3131 SMI(smirc::cfg)->initialise();
3232 SMI(smmon::cfg)->initialise();
 33+ SMI(smlog::log)->initialise();
3334 SMI(smmc::mc)->initialise();
3435 csmplex::csmplexd cm;
3536 cm.start();
Index: trunk/servmon/SConstruct
@@ -35,4 +35,5 @@
3636 env.Command('sminfo.cxx', 'sminfo.sh', '/bin/sh $SOURCE >$TARGET')
3737
3838 env.Program ('servmon', srcs)
 39+env.Program ('smlogmsg', ['smlogmsg.c'])
3940 env.Alias('install', prefix)
Index: trunk/servmon/smlogmsg.c
@@ -0,0 +1,45 @@
 2+#include <sys/socket.h>
 3+#include <sys/un.h>
 4+
 5+#include <stdio.h>
 6+#include <string.h>
 7+#include <stdlib.h>
 8+#include <errno.h>
 9+#include <unistd.h>
 10+
 11+int
 12+main(int argc, char *argv[])
 13+{
 14+ struct sockaddr_un sa;
 15+ socklen_t len;
 16+ int s;
 17+ char *logmsg;
 18+
 19+ if (argc != 3) {
 20+ fprintf(stderr, "usage: %s <log level> <message>\n", argv[0]);
 21+ exit(8);
 22+ }
 23+
 24+ memset(&sa, 0, sizeof(sa));
 25+ sa.sun_family = AF_UNIX;
 26+ strcpy(sa.sun_path, "/tmp/servmon.log");
 27+ len = SUN_LEN(&sa);
 28+
 29+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
 30+ perror("socket");
 31+ exit(8);
 32+ }
 33+
 34+ if (connect(s, (struct sockaddr *)&sa, len) < 0) {
 35+ perror("connect");
 36+ exit(8);
 37+ }
 38+
 39+ logmsg = malloc(strlen(argv[1]) + strlen(argv[2]) + 2);
 40+ sprintf(logmsg, "%s %s", argv[1], argv[2]);
 41+ if (write(s, logmsg, strlen(logmsg)) < 0) {
 42+ perror("write");
 43+ exit(8);
 44+ }
 45+ exit(0);
 46+}
Property changes on: trunk/servmon/smlogmsg.c
___________________________________________________________________
Added: svn:eol-style
147 + native
Added: svn:keywords
248 + Author Date Id Revision
Index: trunk/servmon/smirc.cxx
@@ -315,7 +315,13 @@
316316 sckt->svc(lexical_cast<std::string>(port));
317317 sckt->node(serv);
318318 cip = true;
319 - if (sckt->connect()) { cip = false; connected(); }
 319+ try {
 320+ if (sckt->connect()) { cip = false; connected(); }
 321+ } catch (smnet::sckterr& e) {
 322+ SMI(smlog::log)->logmsg(0, std::string("IRC connection failed: ") + e.what());
 323+ cip = false;
 324+ return;
 325+ }
320326 boost::function<void(smnet::scktp, int)> f =
321327 boost::bind(&ircclnt::data_cb, this, _2);
322328 SMI(smnet::smpx)->add(f, static_pointer_cast<smnet::sckt>(sckt), smnet::smpx::srd /*| smnet::smpx::swr*/);

Status & tagging log