current_service.get_connections()   F
last analyzed

Complexity

Conditions 10

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
rs 3.5555
cc 10

How to fix   Complexity   

Complexity

Complex classes like current_service.get_connections() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# Create your tests here.
2
# Copyright 2013 Mathias WOLFF
3
# This file is part of pyfreebilling.
4
#
5
# pyfreebilling is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# pyfreebilling is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with pyfreebilling. If not, see <http://www.gnu.org/licenses/>
17
#
18
# IMPORTNAT : 
19
# Copyright : a lot of codes from this part come from psdash
20
# thanks for this great work
21
# https://github.com/Jahaja/psdash
22
#
23
# coding=utf-8
24
25
import logging
26
import os
27
import platform
28
import psutil
29
import socket
30
import time
31
import netifaces
32
33
34
def get_interface_addresses():
35
    """
36
    Get addresses of available network interfaces.
37
    See netifaces on pypi for details.
38
39
    Returns a list of dicts
40
    """
41
42
    addresses = []
43
    ifaces = netifaces.interfaces()
44
    for iface in ifaces:
45
        addrs = netifaces.ifaddresses(iface)
46
        families = addrs.keys()
47
48
        # put IPv4 to the end so it lists as the main iface address
49
        if netifaces.AF_INET in families:
50
            families.remove(netifaces.AF_INET)
51
            families.append(netifaces.AF_INET)
52
53
        for family in families:
54
            for addr in addrs[family]:
55
                address = {
56
                    'name': iface,
57
                    'family': family,
58
                    'ip': addr['addr'],
59
                }
60
                addresses.append(address)
61
62
    return addresses
63
64
65
def get_sysinfo():
66
    uptime = int(time.time() - psutil.boot_time())
67
    sysinfo = {
68
        'uptime': uptime,
69
        'hostname': socket.gethostname(),
70
        'os': platform.platform(),
71
        'load_avg': os.getloadavg(),
72
        'num_cpus': psutil.cpu_count()
73
    }
74
    return sysinfo
75
76
def get_memory():
77
    return psutil.virtual_memory()._asdict()
78
79
def get_swap_space():
80
    sm = psutil.swap_memory()
81
    swap = {
82
        'total': sm.total,
83
        'free': sm.free,
84
        'used': sm.used,
85
        'percent': sm.percent,
86
        'swapped_in': sm.sin,
87
        'swapped_out': sm.sout
88
    }
89
    return swap
90
91
def get_cpu():
92
    return psutil.cpu_times_percent(0)._asdict()
93
94
def get_cpu_cores():
95
    return [c._asdict() for c in psutil.cpu_times_percent(0, percpu=True)]
96
97
def get_disks(all_partitions=False):
98
    disks = []
99
    for dp in psutil.disk_partitions(all_partitions):
100
        usage = psutil.disk_usage(dp.mountpoint)
101
        disk = {
102
            'device': dp.device,
103
            'mountpoint': dp.mountpoint,
104
            'type': dp.fstype,
105
            'options': dp.opts,
106
            'space_total': usage.total,
107
            'space_used': usage.used,
108
            'space_used_percent': usage.percent,
109
            'space_free': usage.free
110
        }
111
        disks.append(disk)
112
    return disks
113
114
def get_disks_counters(perdisk=True):
115
    return dict((dev, c._asdict()) for dev, c in psutil.disk_io_counters(perdisk=perdisk).iteritems())
116
117
def get_users():
118
    return [u._asdict() for u in psutil.users()]
119
120
def get_network_interfaces():
121
    io_counters = psutil.net_io_counters(pernic=True)
122
    addresses = get_interface_addresses()
123
    #import pdb; pdb.set_trace()
124
    netifs = {}
125
    for addr in addresses:
126
        c = io_counters[addr['name']]
127
        if not c:
128
            continue
129
        netifs[addr['name']] = {
130
            'name': addr['name'],
131
            'ip': addr['ip'],
132
            'bytes_sent': c.bytes_sent,
133
            'bytes_recv': c.bytes_recv,
134
            'packets_sent': c.packets_sent,
135
            'packets_recv': c.packets_recv,
136
            'errors_in': c.errin,
137
            'errors_out': c.errout,
138
            'dropped_in': c.dropin,
139
            'dropped_out': c.dropout
140
        }
141
    return netifs
142
143
144
class current_service(object):
145
    def __init__(self, node):
146
        self.node = node
147
148
    def get_process_list(self):
149
        process_list = []
150
        for p in psutil.process_iter():
151
            mem = p.memory_info()
152
            proc = {
153
                'pid': p.pid,
154
                'name': p.name(),
155
                'cmdline': ' '.join(p.cmdline()),
156
                'user': p.username(),
157
                'status': p.status(),
158
                'created': p.create_time(),
159
                'mem_rss': mem.rss,
160
                'mem_vms': mem.vms,
161
                'mem_percent': p.memory_percent(),
162
                'cpu_percent': p.cpu_percent(0)
163
            }
164
            process_list.append(proc)
165
166
        return process_list
167
168
    def get_process(self, pid):
169
        p = psutil.Process(pid)
170
        mem = p.memory_info_ex()
171
        cpu_times = p.cpu_times()
172
        return {
173
            'pid': p.pid,
174
            'ppid': p.ppid(),
175
            'parent_name': p.parent().name() if p.parent() else '',
176
            'name': p.name(),
177
            'cmdline': ' '.join(p.cmdline()),
178
            'user': p.username(),
179
            'uid_real': p.uids().real,
180
            'uid_effective': p.uids().effective,
181
            'uid_saved': p.uids().saved,
182
            'gid_real': p.gids().real,
183
            'gid_effective': p.gids().effective,
184
            'gid_saved': p.gids().saved,
185
            'status': p.status(),
186
            'created': p.create_time(),
187
            'terminal': p.terminal(),
188
            'mem_rss': mem.rss,
189
            'mem_vms': mem.vms,
190
            'mem_shared': mem.shared,
191
            'mem_text': mem.text,
192
            'mem_lib': mem.lib,
193
            'mem_data': mem.data,
194
            'mem_dirty': mem.dirty,
195
            'mem_percent': p.memory_percent(),
196
            'cwd': p.cwd(),
197
            'nice': p.nice(),
198
            'io_nice_class': p.ionice()[0],
199
            'io_nice_value': p.ionice()[1],
200
            'cpu_percent': p.cpu_percent(0),
201
            'num_threads': p.num_threads(),
202
            'num_files': len(p.open_files()),
203
            'num_children': len(p.children()),
204
            'num_ctx_switches_invol': p.num_ctx_switches().involuntary,
205
            'num_ctx_switches_vol': p.num_ctx_switches().voluntary,
206
            'cpu_times_user': cpu_times.user,
207
            'cpu_times_system': cpu_times.system,
208
            'cpu_affinity': p.cpu_affinity()
209
        }
210
211
    def get_process_limits(self, pid):
212
        p = psutil.Process(pid)
213
        return {
214
            'RLIMIT_AS': p.rlimit(psutil.RLIMIT_AS),
215
            'RLIMIT_CORE': p.rlimit(psutil.RLIMIT_CORE),
216
            'RLIMIT_CPU': p.rlimit(psutil.RLIMIT_CPU),
217
            'RLIMIT_DATA': p.rlimit(psutil.RLIMIT_DATA),
218
            'RLIMIT_FSIZE': p.rlimit(psutil.RLIMIT_FSIZE),
219
            'RLIMIT_LOCKS': p.rlimit(psutil.RLIMIT_LOCKS),
220
            'RLIMIT_MEMLOCK': p.rlimit(psutil.RLIMIT_MEMLOCK),
221
            'RLIMIT_MSGQUEUE': p.rlimit(psutil.RLIMIT_MSGQUEUE),
222
            'RLIMIT_NICE': p.rlimit(psutil.RLIMIT_NICE),
223
            'RLIMIT_NOFILE': p.rlimit(psutil.RLIMIT_NOFILE),
224
            'RLIMIT_NPROC': p.rlimit(psutil.RLIMIT_NPROC),
225
            'RLIMIT_RSS': p.rlimit(psutil.RLIMIT_RSS),
226
            'RLIMIT_RTPRIO': p.rlimit(psutil.RLIMIT_RTPRIO),
227
            'RLIMIT_RTTIME': p.rlimit(psutil.RLIMIT_RTTIME),
228
            'RLIMIT_SIGPENDING': p.rlimit(psutil.RLIMIT_SIGPENDING),
229
            'RLIMIT_STACK': p.rlimit(psutil.RLIMIT_STACK)
230
        }
231
232
    def get_process_environment(self, pid):
233
        with open('/proc/%d/environ' % pid) as f:
234
            contents = f.read()
235
            env_vars = dict(row.split('=', 1) for row in contents.split('\0') if '=' in row)
236
        return env_vars
237
238
    def get_process_threads(self, pid):
239
        threads = []
240
        proc = psutil.Process(pid)
241
        for t in proc.threads():
242
            thread = {
243
                'id': t.id,
244
                'cpu_time_user': t.user_time,
245
                'cpu_time_system': t.system_time,
246
            }
247
            threads.append(thread)
248
        return threads
249
250
    def get_process_open_files(self, pid):
251
        proc = psutil.Process(pid)
252
        return [f._asdict() for f in proc.open_files()]
253
254
    def get_process_connections(self, pid):
255
        proc = psutil.Process(pid)
256
        connections = []
257
        for c in proc.connections(kind='all'):
258
            conn = {
259
                'fd': c.fd,
260
                'family': socket_families[c.family],
261
                'type': socket_types[c.type],
262
                'local_addr_host': c.laddr[0] if c.laddr else None,
263
                'local_addr_port': c.laddr[1] if c.laddr else None,
264
                'remote_addr_host': c.raddr[0] if c.raddr else None,
265
                'remote_addr_port': c.raddr[1] if c.raddr else None,
266
                'state': c.status
267
            }
268
            connections.append(conn)
269
270
        return connections
271
272
    def get_process_memory_maps(self, pid):
273
        return [m._asdict() for m in psutil.Process(pid).memory_maps()]
274
275
    def get_process_children(self, pid):
276
        proc = psutil.Process(pid)
277
        children = []
278
        for c in proc.children():
279
            child = {
280
                'pid': c.pid,
281
                'name': c.name(),
282
                'cmdline': ' '.join(c.cmdline()),
283
                'status': c.status()
284
            }
285
            children.append(child)
286
287
        return children
288
289
    def get_connections(self, filters=None):
290
        filters = filters or {}
291
        connections = []
292
293
        for c in psutil.net_connections('all'):
294
            conn = {
295
                'fd': c.fd,
296
                'pid': c.pid,
297
                'family': socket_families[c.family],
298
                'type': socket_types[c.type],
299
                'local_addr_host': c.laddr[0] if c.laddr else None,
300
                'local_addr_port': c.laddr[1] if c.laddr else None,
301
                'remote_addr_host': c.raddr[0] if c.raddr else None,
302
                'remote_addr_port': c.raddr[1] if c.raddr else None,
303
                'state': c.status
304
            }
305
306
            for k, v in filters.iteritems():
307
                if v and conn.get(k) != v:
308
                    break
309
            else:
310
                connections.append(conn)
311
312
        return connections
313
314
    def get_logs(self):
315
        available_logs = []
316
        for log in self.node.logs.get_available():
317
            try:
318
                stat = os.stat(log.filename)
319
                available_logs.append({
320
                    'path': log.filename,
321
                    'size': stat.st_size,
322
                    'atime': stat.st_atime,
323
                    'mtime': stat.st_mtime
324
                })
325
            except OSError:
326
                logger.info('Could not stat "%s", removing from available logs', log.filename)
327
                self.node.logs.remove_available(log.filename)
328
329
        return available_logs
330
331
    def read_log(self, filename, session_key=None, seek_tail=False):
332
        log = self.node.logs.get(filename, key=session_key)
333
        if seek_tail:
334
            log.set_tail_position()
335
        return log.read()
336
337
    def search_log(self, filename, text, session_key=None):
338
        log = self.node.logs.get(filename, key=session_key)
339
        pos, bufferpos, res = log.search(text)
340
        stat = os.stat(log.filename)
341
        data = {
342
            'position': pos,
343
            'buffer_pos': bufferpos,
344
            'filesize': stat.st_size,
345
            'content': res
346
        }
347
        return data