collect-master.py 3.36 KB
Newer Older
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
1
#!/usr/bin/python2
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
#    Ucollect - small utility for real-time analysis of network data
#    Copyright (C) 2013 CZ.NIC
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

21
22
23
24
from twisted.internet import reactor, ssl, protocol
from twisted.internet.endpoints import UNIXServerEndpoint
from twisted.internet.error import ReactorNotRunning
from subprocess import Popen
25
import log_extra
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
26
import logging
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
27
import logging.handlers
28
from client import ClientFactory
29
from plugin import Plugins
30
import master_config
31
import activity
32
import importlib
33
import os
34

35
36
37
38
39
severity = master_config.get('log_severity')
if severity == 'TRACE':
	severity = log_extra.TRACE_LEVEL
else:
	severity = getattr(logging, severity)
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
40
log_file = master_config.get('log_file')
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
41
42
logging.basicConfig(level=severity, format=master_config.get('log_format'))
if log_file != '-':
43
44
45
	handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=int(master_config.get('log_file_size')), backupCount=int(master_config.get('log_file_count')))
	handler.setFormatter(logging.Formatter(fmt=master_config.get('log_format')))
	logging.getLogger().addHandler(handler)
46
47

loaded_plugins = {}
48
plugins = Plugins()
49
50
51
52
53
54
for (plugin, config) in master_config.plugins().items():
	(modulename, classname) = plugin.rsplit('.', 1)
	module = importlib.import_module(modulename)
	constructor = getattr(module, classname)
	loaded_plugins[plugin] = constructor(plugins, config)
	logging.info('Loaded plugin %s from %s', loaded_plugins[plugin].name(), plugin)
55
# Some configuration, to load the port from?
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
endpoint = UNIXServerEndpoint(reactor, './collect-master.sock')

socat = None

class Socat(protocol.ProcessProtocol):
	def connectionMade(self):
		global socat
		socat = self.transport
		logging.info('Started socat proxy')

	def processEnded(self, status):
		global socat
		if socat:
			socat = None
			try:
				reactor.stop()
				# Don't report lost socat if we're already terminating
				logging.fatal('Lost socat, terminating')
			except ReactorNotRunning:
				pass

	def errReceived(self, data):
		logging.warn('Socat complained: %s', data)

80
args = ['socat', 'OPENSSL-LISTEN:' + str(master_config.getint('port')) + ',fork,backlog=50,key=' + master_config.get('key') + ',cert=' + master_config.get('cert') + ',verify=0,cipher=HIGH:!LOW:!MEDIUM:!SSLv2:!aNULL:!eNULL:!DES:!3DES:!AES128:!CAMELLIA128,reuseaddr,pf=ip6,compress=auto,method=TLS', 'UNIX-CONNECT:./collect-master.sock']
81
logging.debug('Starting socat with: %s', args)
82
reactor.spawnProcess(Socat(), 'socat', args=args, env=os.environ)
83
endpoint.listen(ClientFactory(plugins))
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
84
logging.info('Init done')
85

86
reactor.run()
87
88

logging.info('Finishing up')
89
90
91
92
if socat:
	soc = socat
	socat = None
	soc.signalProcess('TERM')
93
94
activity.shutdown()
logging.info('Shutdown done')