Last active
December 14, 2017 14:12
-
-
Save julian7/e45f4ca4798a02dcd14f to your computer and use it in GitHub Desktop.
Syslog server for docker images: outputs everything to stdout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <strings.h> | |
#include <errno.h> | |
#include <ctype.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#define BUFSIZE 4096 | |
#define DEBUG(...) | |
//#define DEBUG(...) printf(__VA_ARGS__) | |
static char pri[8][7] = { | |
"emerg", "alert", "crit", "error", "warn", "notice", "info", "debug" | |
}; | |
static char fac[24][9] = { | |
"kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", | |
"cron", "authpriv", "ftp", "kern1", "kern2", "kern3", "kern4", "local0", | |
"local1", "local2", "local3", "local4", "local5", "local6", "local7" | |
}; | |
void failerr(char *what, int when) { | |
if (when == -1) { | |
perror(what); | |
exit(1); | |
} | |
} | |
void handle_log(char *entry) { | |
char *p, c; | |
int facpriv = 0; | |
p = entry; | |
if (*p == '<') { | |
while(isdigit(*++p)) { | |
facpriv = 10 * facpriv + *p -'0'; | |
} | |
if (*p == '>') { | |
++p; | |
} | |
} | |
printf("<%s.%s> %s\n", fac[facpriv >> 3], pri[facpriv & 7], p); | |
} | |
int main() { | |
unsigned int fd_listen; | |
struct sockaddr_un local; | |
char buf[BUFSIZE]; | |
local.sun_family = AF_UNIX; | |
strcpy(local.sun_path, "/dev/log"); | |
unlink(local.sun_path); | |
failerr("socket", (fd_listen = socket(AF_UNIX, SOCK_STREAM, 0))); | |
failerr("bind", bind(fd_listen, (struct sockaddr *)&local, | |
strlen(local.sun_path) + sizeof(local.sun_family))); | |
failerr("listen", listen(fd_listen, 5)); | |
for(;;) { | |
int done, fd_conn, n, t; | |
struct sockaddr_un remote; | |
t = sizeof(remote); | |
failerr("accept", (fd_conn = accept(fd_listen, (struct sockaddr *)&remote, &t))); | |
DEBUG("Accepted connection\n"); | |
done = 0; | |
do { | |
n = recv(fd_conn, buf, BUFSIZE, 0); | |
DEBUG("Received %d bytes of input\n", n); | |
if (n <= 0) { | |
if (n < 0) perror("recv"); | |
done = 1; | |
DEBUG("Want to close\n"); | |
} else { | |
buf[n] = '\0'; | |
handle_log(buf); | |
} | |
} while (!done); | |
close(fd_conn); | |
DEBUG("Closed connection\n"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import sys | |
import socket | |
import signal | |
import string | |
bufsiz = 4096 | |
class SyslogListener(object): | |
PRIO = ["emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"] | |
FACILITY = ["kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", | |
"uucp", "cron", "authpriv", "ftp", "ntp", "security", "console", "mark", | |
"local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"] | |
def __init__(self, sockname): | |
self.sockname = sockname | |
self.sock = None | |
self.wantstop = False | |
self.signals = {} | |
self.signals[signal.SIGINT] = "SIGINT" | |
self.signals[signal.SIGTERM] = "SIGTERM" | |
signal.signal(signal.SIGINT, self.sighandler) | |
signal.signal(signal.SIGTERM, self.sighandler) | |
def listen(self): | |
self.cleanSocketFile | |
try: | |
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) | |
sock.bind(self.sockname) | |
self.sock = sock | |
except: | |
self.generalException("Socket error") | |
while self.wantstop != True: | |
try: | |
data, addr = sock.recvfrom(bufsiz) | |
print self.formatData(data, addr) | |
except socket.error: | |
pass | |
except: | |
self.generalException("Error") | |
self.shutdown | |
self.cleanSocketFile | |
def generalException(self, message): | |
xinfo = sys.exc_info() | |
print "{0}: {{1}} {2}, initiating shutdown".format(message, xinfo[0], xinfo[1]) | |
self.wantstop = True | |
def cleanSocketFile(self): | |
try: | |
os.remove(self.sockname) | |
except: | |
pass | |
def formatData(self, data, addr): | |
delim = string.find(data, '>') | |
priofac = int(data[1:delim]) | |
return "<{0}.{1}> {2}".format(self.FACILITY[priofac >> 3], | |
self.PRIO[priofac & 7], data[delim+1:]) | |
def sighandler(self, signum, _frame): | |
print "Signal {0} caught, initiating shutdown".format(self.signals[signum]) | |
self.wantstop = True | |
def shutdown(self): | |
try: | |
self.sock.close() | |
except: | |
pass | |
if __name__ == '__main__': | |
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) | |
listener = SyslogListener((sys.argv[1:2] or ["/dev/log"])[0]) | |
listener.listen() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment