-
Notifications
You must be signed in to change notification settings - Fork 32
/
sources.py
131 lines (110 loc) · 4.23 KB
/
sources.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from subprocess import Popen, PIPE, STDOUT
class SourceBase(object):
"""Subclasses should define instance attributes self.ssh_params,
self.cmd, self.encoding and optionally the instance method
self.filter() self.ssh_params is a dict containing the parameters
to pass to the ssh command. At a minimum, it should define
self.ssh_params['hostname']. It may also define other ssh options
such as 'host', 'user' or 'identityfile'. Option names are the
same as those used in the ssh config file, except in
lowercase. For more information see the man page for
ssh_config. The 'host' option is used as a nickname. If 'host' is
not specified, the value for 'hostname' is assigned to 'host'.
Example self.ssh_params:
{'host': 'us-ng1',
'hostname': '111.111.111.15',
'identityfile': '/home/saltycrane/sshkeys/myprivatekey',
'user': 'myusername',
}
"""
def start_stream(self):
self._assemble_ssh_command()
self.p = Popen(self.ssh_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
def _assemble_ssh_command(self):
if 'host' not in self.ssh_params:
self.ssh_params['host'] = self.ssh_params['hostname']
ssh_options = ' -o'.join(['='.join([k, v])
for k, v in self.ssh_params.iteritems()
if k != 'hostname' and k != 'host'])
if ssh_options:
ssh_options = '-o' + ssh_options
self.ssh_cmd = ' '.join(['ssh',
ssh_options,
self.ssh_params['hostname'],
'"%s"' % self.cmd,
])
def get_line(self):
while True:
line = self.p.stdout.readline()
if line == '' and self.p.poll() != None:
raise Exception('Child process exited for host %s: %s' % (
self.ssh_params['host'], self.cmd))
line = unicode(line, encoding=self.encoding, errors='replace')
line = self.filter(line)
if line:
break
return line
def filter(self, line):
"""To skip a line return an empty string ('')
Otherwise, return the line.
"""
return line
class SourceLog(SourceBase):
"""A source log file on a remote host.
"""
def __init__(self, ssh_params, filepath, encoding='utf-8'):
self.ssh_params = ssh_params
self.encoding = encoding
self.cmd = 'tail --follow=name %s' % filepath
class MysqladminExtendedRelativeSource(SourceBase):
"""Get data from mysqladmin extended command (relative)
"""
def __init__(self, ssh_params, encoding='utf-8'):
self.ssh_params = ssh_params
self.encoding = encoding
self.cmd = 'mysqladmin extended -i10 -r'
def filter(self, line):
if ('Questions' in line or
'Slow_queries' in line):
return line
else:
return ''
class MysqladminExtendedAbsoluteSource(SourceBase):
"""Get data from mysqladmin extended command (absolute)
"""
def __init__(self, ssh_params, encoding='utf-8'):
self.ssh_params = ssh_params
self.encoding = encoding
self.cmd = 'mysqladmin extended'
def filter(self, line):
if ('Slave_running' in line or
'Threads_connected' in line or
'Threads_running' in line):
return line
else:
return ''
class VmstatSource(SourceBase):
"""Get data from vmstat
"""
def __init__(self, ssh_params, encoding='utf-8'):
self.ssh_params = ssh_params
self.encoding = encoding
self.cmd = 'vmstat 5'
def filter(self, line):
if (line.startswith('procs') or
line.startswith(' r')):
return ''
else:
return line
class DfSource(SourceBase):
"""Get data from "df"
"""
def __init__(self, ssh_params, filepath, encoding='utf-8'):
self.ssh_params = ssh_params
self.encoding = encoding
self.cmd = 'while [ 1 ]; do df %s; sleep 60; done' % filepath
def filter(self, line):
if line.startswith('Filesystem'):
return ''
else:
return line