/* syslog for the trli project. This program does not write to disk. All in memory. */ #include #include #include #include #include #include #include #include #include #include #include #include "fdpass.h" using namespace std; enum CONNECT_TYPE { TYPE_NONE, TYPE_CONTROL, TYPE_CLIENT }; struct HANDLE_INFO: public ARRAY_OBJ{ CONNECT_TYPE type; REQUEST_INFO req; }; #include "proto/trli_syslog_control.protoh" static void copy_lines (const deque &logs, unsigned offset, unsigned nblines, vector &tb) { size_t size = logs.size(); if (offset < size && nblines > 0){ for (auto l = logs.begin() + offset; l != logs.end() && nblines > 0; l++, nblines--){ tb.push_back(*l); } } } int main (int argc, char *argv[]) { glocal const char *control = "/var/run/bkackhole/trli-syslog.sock"; glocal const char *logport = "/dev/trli.log"; glocal const char *pidfile = "/var/run/trli-syslog.pid"; glocal const char *user = "trli"; glocal bool daemon = false; glocal int ret = -1; glocal.ret = (argc,argv); setproginfo ("trli-syslog",VERSION,"Syslog for trli applications"); setarg ('c',"control","Unix socket to control the application",glocal.control,false); setarg ('l',"logport","Unix socket used to retrieve log messages",glocal.logport,false); setgrouparg ("Daemon mode"); setarg (' ',"daemon","Runs in background",glocal.daemon,false); setarg (' ',"user","Runs as this user",glocal.user,false); setarg (' ',"pidfile","PID file",glocal.pidfile,false); int ret = -1; glocal time_t lastmsg = time(NULL); glocal unsigned nberrors = 0; glocal deque logs; (string_f("unix:%s",glocal.logport),5); if (strncmp(info.port,"unix:",5)==0i){ const char *port5 = info.port+5; if (strcmp(info.port+5,glocal.logport)==0){ HANDLE_INFO *n = new HANDLE_INFO; n->type = TYPE_CLIENT; info.data = n; }else if (strcmp(port5,glocal.control)==0){ HANDLE_INFO *n = new HANDLE_INFO; n->type = TYPE_CONTROL; info.data = n; }else{ tlmp_error ("Unknown connection\n"); endclient = true; } }else{ tlmp_error ("Unknown connection\n"); endclient = true; } HANDLE_INFO *c = (HANDLE_INFO*)info.data; if (c->type == TYPE_CONTROL){ (this,c->req,line, info.linelen,endserver, endclient, no,c); vector tb; tb.push_back(string_f("Version %s",VERSION)); char date[20]; fdpass_asctime (glocal.lastmsg,date); tb.push_back(string_f("last message %s",date)); tb.push_back(string_f("errors: %u",glocal.nberrors)); rep_status(tb); glocal.nberrors = 0; glocal.logs.clear(); vector tb; size_t size = glocal.logs.size(); copy_lines (glocal.logs,offset,nblines,tb); rep_logs (tb,size); vector tb; size_t size = glocal.logs.size(); unsigned nblines = 10; unsigned offset = size-10; if (size < 10){ offset = 0; nblines = size; } copy_lines (glocal.logs,offset,nblines,tb); rep_tail (tb,size,glocal.lastmsg); endserver = true; if (on){ debug_seton(); }else{ debug_setoff(); } debug_setfdebug (filename); endclient = true; }else if (c->type == TYPE_CLIENT){ glocal.lastmsg = time(NULL); if (strncmp(line,"<11>",4)==0) glocal.nberrors++; string tmp(line); strip_end (tmp); glocal.logs.push_back(tmp); if (glocal.logs.size() > 1000) glocal.logs.pop_front(); } if (o.is_ok()){ if (fdpass_setcontrol(o,glocal.control,glocal.user)==-1){ tlmp_error ("Can't setup control socket %s, ending\n",glocal.control); exit (-1); } o.setrawmode (true); ret = 0; if (glocal.daemon){ daemon_init (glocal.pidfile,glocal.user); } o.loop(); }else{ tlmp_error ("Can't bind to %s (%s)\n",glocal.logport,strerror(errno)); } return ret; return glocal.ret; }