| Total Complexity | 40 |
| Total Lines | 204 |
| Duplicated Lines | 20.1 % |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like current_service 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. |
||
| 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 | View Code Duplication | 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 | View Code Duplication | 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 |