Skip to content

Commit e3f594c

Browse files
authored
Merge pull request #44 from fatpat/openio_syslog_logger
add gridinit-syslog-logger tool
2 parents d8104ec + be86cad commit e3f594c

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

tools/gridinit-syslog-logger

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python3
2+
3+
# gridinit, a monitor for non-daemon processes.
4+
# Copyright (C) 2015-2020 OpenIO SAS
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as
8+
# published by the Free Software Foundation, either version 3 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
20+
#
21+
# This program intends to run a program and logs its stdout/stderr to both
22+
# syslog and local console
23+
#
24+
25+
import sys
26+
import os
27+
import signal
28+
import logging
29+
from logging.handlers import SysLogHandler
30+
from logging import StreamHandler
31+
import argparse
32+
33+
#
34+
# Manage args
35+
#
36+
parser = argparse.ArgumentParser()
37+
parser.add_argument("-f", "--facility", type=str, default="daemon", help="syslog facility (daemon)")
38+
parser.add_argument("-p", "--pid", action='store_true', help="log pid (yes)")
39+
parser.add_argument("-i", "--ident", type=str, help="specify logging ident (program name)")
40+
parser.add_argument("program", type=str, help="program to run")
41+
parser.add_argument("args", type=str, nargs='*', help="program arguments")
42+
args = parser.parse_args()
43+
44+
45+
#
46+
# ARGS
47+
#
48+
if not args.ident:
49+
args.ident = os.path.basename(args.program)
50+
51+
if args.pid:
52+
ident = "%s[%d]" % (args.ident , os.getpid())
53+
else:
54+
ident = args.ident
55+
56+
#
57+
# Prepare logging
58+
#
59+
log = logging.getLogger('syslog')
60+
log.setLevel(logging.DEBUG)
61+
syslog_handler = SysLogHandler(address = '/dev/log', facility = args.facility)
62+
syslog_handler.ident = "%s: " % ident
63+
log.addHandler(syslog_handler)
64+
65+
stdout_handler = StreamHandler(stream=sys.stdout)
66+
stdout_handler.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
67+
log.addHandler(stdout_handler)
68+
69+
#
70+
# Fork
71+
#
72+
(pipe_r, pipe_w) = os.pipe()
73+
pid = os.fork()
74+
if pid == 0:
75+
#
76+
# Children
77+
#
78+
79+
# close useless pipe
80+
os.close(pipe_r)
81+
82+
# reopen stdout/stderr into the pipe to the parent process
83+
os.dup2(pipe_w, sys.stdout.fileno())
84+
os.dup2(pipe_w, sys.stderr.fileno())
85+
86+
# exec the program
87+
os.execv(args.program, [os.path.basename(args.program)] + args.args)
88+
89+
# sould never happen
90+
sys.exit(1)
91+
92+
#
93+
# Parent
94+
#
95+
96+
# close useless pipe
97+
os.close(pipe_w)
98+
99+
# open usefull pipe :)
100+
stdin = open(pipe_r, 'r')
101+
102+
#
103+
# forward all signals to the child process
104+
#
105+
def sendToChildren(signum, frame):
106+
os.kill(pid, signum)
107+
for s in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGUSR1, signal.SIGUSR2, signal.SIGABRT, signal.SIGALRM, signal.SIGCONT, signal.SIGINT]:
108+
signal.signal(s, sendToChildren)
109+
110+
#
111+
# Try to change the process name but don't bother if something goes wrong
112+
#
113+
try:
114+
from setproctitle import setproctitle
115+
setproctitle("%s: %s" % (os.path.basename(sys.argv[0]), args.ident))
116+
except:
117+
pass
118+
119+
#
120+
# Update the syslog ident with the new child PID
121+
#
122+
if args.pid:
123+
syslog_handler.ident = "%s[%d]: " % (args.ident , pid)
124+
125+
#
126+
# Loop forever waiting for child stdout in order to log it
127+
#
128+
while True:
129+
data = stdin.readline()
130+
if not data: break
131+
log.info(data.strip())
132+
sys.exit(0)

0 commit comments

Comments
 (0)