psutil

Форк
0
/
procinfo.py 
341 строка · 11.6 Кб
1
#!/usr/bin/env python3
2

3
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
4
# Use of this source code is governed by a BSD-style license that can be
5
# found in the LICENSE file.
6

7
"""Print detailed information about a process.
8

9
Author: Giampaolo Rodola' <g.rodola@gmail.com>
10

11
$ python3 scripts/procinfo.py
12
pid           4600
13
name          chrome
14
parent        4554 (bash)
15
exe           /opt/google/chrome/chrome
16
cwd           /home/giampaolo
17
cmdline       /opt/google/chrome/chrome
18
started       2016-09-19 11:12
19
cpu-tspent    27:27.68
20
cpu-times     user=8914.32, system=3530.59,
21
              children_user=1.46, children_system=1.31
22
cpu-affinity  [0, 1, 2, 3, 4, 5, 6, 7]
23
memory        rss=520.5M, vms=1.9G, shared=132.6M, text=95.0M, lib=0B,
24
              data=816.5M, dirty=0B
25
memory %      3.26
26
user          giampaolo
27
uids          real=1000, effective=1000, saved=1000
28
uids          real=1000, effective=1000, saved=1000
29
terminal      /dev/pts/2
30
status        sleeping
31
nice          0
32
ionice        class=IOPriority.IOPRIO_CLASS_NONE, value=0
33
num-threads   47
34
num-fds       379
35
I/O           read_count=96.6M, write_count=80.7M,
36
              read_bytes=293.2M, write_bytes=24.5G
37
ctx-switches  voluntary=30426463, involuntary=460108
38
children      PID    NAME
39
              4605   cat
40
              4606   cat
41
              4609   chrome
42
              4669   chrome
43
open-files    PATH
44
              /opt/google/chrome/icudtl.dat
45
              /opt/google/chrome/snapshot_blob.bin
46
              /opt/google/chrome/natives_blob.bin
47
              /opt/google/chrome/chrome_100_percent.pak
48
              [...]
49
connections   PROTO LOCAL ADDR            REMOTE ADDR               STATUS
50
              UDP   10.0.0.3:3693         *:*                       NONE
51
              TCP   10.0.0.3:55102        172.217.22.14:443         ESTABLISHED
52
              UDP   10.0.0.3:35172        *:*                       NONE
53
              TCP   10.0.0.3:32922        172.217.16.163:443        ESTABLISHED
54
              UDP   :::5353               *:*                       NONE
55
              UDP   10.0.0.3:59925        *:*                       NONE
56
threads       TID              USER          SYSTEM
57
              11795             0.7            1.35
58
              11796            0.68            1.37
59
              15887            0.74            0.03
60
              19055            0.77            0.01
61
              [...]
62
              total=47
63
res-limits    RLIMIT                     SOFT       HARD
64
              virtualmem             infinity   infinity
65
              coredumpsize                  0   infinity
66
              cputime                infinity   infinity
67
              datasize               infinity   infinity
68
              filesize               infinity   infinity
69
              locks                  infinity   infinity
70
              memlock                   65536      65536
71
              msgqueue                 819200     819200
72
              nice                          0          0
73
              openfiles                  8192      65536
74
              maxprocesses              63304      63304
75
              rss                    infinity   infinity
76
              realtimeprio                  0          0
77
              rtimesched             infinity   infinity
78
              sigspending               63304      63304
79
              stack                   8388608   infinity
80
mem-maps      RSS      PATH
81
              381.4M   [anon]
82
              62.8M    /opt/google/chrome/chrome
83
              15.8M    /home/giampaolo/.config/google-chrome/Default/History
84
              6.6M     /home/giampaolo/.config/google-chrome/Default/Favicons
85
              [...]
86
"""
87

88
import argparse
89
import datetime
90
import socket
91
import sys
92

93
import psutil
94
from psutil._common import bytes2human
95

96

97
ACCESS_DENIED = ''
98
NON_VERBOSE_ITERATIONS = 4
99
RLIMITS_MAP = {
100
    "RLIMIT_AS": "virtualmem",
101
    "RLIMIT_CORE": "coredumpsize",
102
    "RLIMIT_CPU": "cputime",
103
    "RLIMIT_DATA": "datasize",
104
    "RLIMIT_FSIZE": "filesize",
105
    "RLIMIT_MEMLOCK": "memlock",
106
    "RLIMIT_MSGQUEUE": "msgqueue",
107
    "RLIMIT_NICE": "nice",
108
    "RLIMIT_NOFILE": "openfiles",
109
    "RLIMIT_NPROC": "maxprocesses",
110
    "RLIMIT_NPTS": "pseudoterms",
111
    "RLIMIT_RSS": "rss",
112
    "RLIMIT_RTPRIO": "realtimeprio",
113
    "RLIMIT_RTTIME": "rtimesched",
114
    "RLIMIT_SBSIZE": "sockbufsize",
115
    "RLIMIT_SIGPENDING": "sigspending",
116
    "RLIMIT_STACK": "stack",
117
    "RLIMIT_SWAP": "swapuse",
118
}
119

120

121
def print_(a, b):
122
    if sys.stdout.isatty() and psutil.POSIX:
123
        fmt = '\x1b[1;32m%-13s\x1b[0m %s' % (a, b)
124
    else:
125
        fmt = '%-11s %s' % (a, b)
126
    print(fmt)
127

128

129
def str_ntuple(nt, convert_bytes=False):
130
    if nt == ACCESS_DENIED:
131
        return ""
132
    if not convert_bytes:
133
        return ", ".join(["%s=%s" % (x, getattr(nt, x)) for x in nt._fields])
134
    else:
135
        return ", ".join(
136
            ["%s=%s" % (x, bytes2human(getattr(nt, x))) for x in nt._fields]
137
        )
138

139

140
def run(pid, verbose=False):
141
    try:
142
        proc = psutil.Process(pid)
143
        pinfo = proc.as_dict(ad_value=ACCESS_DENIED)
144
    except psutil.NoSuchProcess as err:
145
        sys.exit(str(err))
146

147
    # collect other proc info
148
    with proc.oneshot():
149
        try:
150
            parent = proc.parent()
151
            parent = '(%s)' % parent.name() if parent else ''
152
        except psutil.Error:
153
            parent = ''
154
        try:
155
            pinfo['children'] = proc.children()
156
        except psutil.Error:
157
            pinfo['children'] = []
158
        if pinfo['create_time']:
159
            started = datetime.datetime.fromtimestamp(
160
                pinfo['create_time']
161
            ).strftime('%Y-%m-%d %H:%M')
162
        else:
163
            started = ACCESS_DENIED
164

165
    # here we go
166
    print_('pid', pinfo['pid'])
167
    print_('name', pinfo['name'])
168
    print_('parent', '%s %s' % (pinfo['ppid'], parent))
169
    print_('exe', pinfo['exe'])
170
    print_('cwd', pinfo['cwd'])
171
    print_('cmdline', ' '.join(pinfo['cmdline']))
172
    print_('started', started)
173

174
    cpu_tot_time = datetime.timedelta(seconds=sum(pinfo['cpu_times']))
175
    cpu_tot_time = "%s:%s.%s" % (
176
        cpu_tot_time.seconds // 60 % 60,
177
        str(cpu_tot_time.seconds % 60).zfill(2),
178
        str(cpu_tot_time.microseconds)[:2],
179
    )
180
    print_('cpu-tspent', cpu_tot_time)
181
    print_('cpu-times', str_ntuple(pinfo['cpu_times']))
182
    if hasattr(proc, "cpu_affinity"):
183
        print_("cpu-affinity", pinfo["cpu_affinity"])
184
    if hasattr(proc, "cpu_num"):
185
        print_("cpu-num", pinfo["cpu_num"])
186

187
    print_('memory', str_ntuple(pinfo['memory_info'], convert_bytes=True))
188
    print_('memory %', round(pinfo['memory_percent'], 2))
189
    print_('user', pinfo['username'])
190
    if psutil.POSIX:
191
        print_('uids', str_ntuple(pinfo['uids']))
192
    if psutil.POSIX:
193
        print_('uids', str_ntuple(pinfo['uids']))
194
    if psutil.POSIX:
195
        print_('terminal', pinfo['terminal'] or '')
196

197
    print_('status', pinfo['status'])
198
    print_('nice', pinfo['nice'])
199
    if hasattr(proc, "ionice"):
200
        try:
201
            ionice = proc.ionice()
202
        except psutil.Error:
203
            pass
204
        else:
205
            if psutil.WINDOWS:
206
                print_("ionice", ionice)
207
            else:
208
                print_(
209
                    "ionice",
210
                    "class=%s, value=%s" % (str(ionice.ioclass), ionice.value),
211
                )
212

213
    print_('num-threads', pinfo['num_threads'])
214
    if psutil.POSIX:
215
        print_('num-fds', pinfo['num_fds'])
216
    if psutil.WINDOWS:
217
        print_('num-handles', pinfo['num_handles'])
218

219
    if 'io_counters' in pinfo:
220
        print_('I/O', str_ntuple(pinfo['io_counters'], convert_bytes=True))
221
    if 'num_ctx_switches' in pinfo:
222
        print_("ctx-switches", str_ntuple(pinfo['num_ctx_switches']))
223
    if pinfo['children']:
224
        template = "%-6s %s"
225
        print_("children", template % ("PID", "NAME"))
226
        for child in pinfo['children']:
227
            try:
228
                print_('', template % (child.pid, child.name()))
229
            except psutil.AccessDenied:
230
                print_('', template % (child.pid, ""))
231
            except psutil.NoSuchProcess:
232
                pass
233

234
    if pinfo['open_files']:
235
        print_('open-files', 'PATH')
236
        for i, file in enumerate(pinfo['open_files']):
237
            if not verbose and i >= NON_VERBOSE_ITERATIONS:
238
                print_("", "[...]")
239
                break
240
            print_('', file.path)
241
    else:
242
        print_('open-files', '')
243

244
    if pinfo['net_connections']:
245
        template = '%-5s %-25s %-25s %s'
246
        print_(
247
            'connections',
248
            template % ('PROTO', 'LOCAL ADDR', 'REMOTE ADDR', 'STATUS'),
249
        )
250
        for conn in pinfo['net_connections']:
251
            if conn.type == socket.SOCK_STREAM:
252
                type = 'TCP'
253
            elif conn.type == socket.SOCK_DGRAM:
254
                type = 'UDP'
255
            else:
256
                type = 'UNIX'
257
            lip, lport = conn.laddr
258
            if not conn.raddr:
259
                rip, rport = '*', '*'
260
            else:
261
                rip, rport = conn.raddr
262
            line = template % (
263
                type,
264
                "%s:%s" % (lip, lport),
265
                "%s:%s" % (rip, rport),
266
                conn.status,
267
            )
268
            print_('', line)
269
    else:
270
        print_('connections', '')
271

272
    if pinfo['threads'] and len(pinfo['threads']) > 1:
273
        template = "%-5s %12s %12s"
274
        print_('threads', template % ("TID", "USER", "SYSTEM"))
275
        for i, thread in enumerate(pinfo['threads']):
276
            if not verbose and i >= NON_VERBOSE_ITERATIONS:
277
                print_("", "[...]")
278
                break
279
            print_('', template % thread)
280
        print_('', "total=%s" % len(pinfo['threads']))
281
    else:
282
        print_('threads', '')
283

284
    if hasattr(proc, "rlimit"):
285
        res_names = [x for x in dir(psutil) if x.startswith("RLIMIT")]
286
        resources = []
287
        for res_name in res_names:
288
            try:
289
                soft, hard = proc.rlimit(getattr(psutil, res_name))
290
            except psutil.AccessDenied:
291
                pass
292
            else:
293
                resources.append((res_name, soft, hard))
294
        if resources:
295
            template = "%-12s %15s %15s"
296
            print_("res-limits", template % ("RLIMIT", "SOFT", "HARD"))
297
            for res_name, soft, hard in resources:
298
                if soft == psutil.RLIM_INFINITY:
299
                    soft = "infinity"
300
                if hard == psutil.RLIM_INFINITY:
301
                    hard = "infinity"
302
                print_(
303
                    '',
304
                    template
305
                    % (RLIMITS_MAP.get(res_name, res_name), soft, hard),
306
                )
307

308
    if hasattr(proc, "environ") and pinfo['environ']:
309
        template = "%-25s %s"
310
        print_("environ", template % ("NAME", "VALUE"))
311
        for i, k in enumerate(sorted(pinfo['environ'])):
312
            if not verbose and i >= NON_VERBOSE_ITERATIONS:
313
                print_("", "[...]")
314
                break
315
            print_("", template % (k, pinfo['environ'][k]))
316

317
    if pinfo.get('memory_maps', None):
318
        template = "%-8s %s"
319
        print_("mem-maps", template % ("RSS", "PATH"))
320
        maps = sorted(pinfo['memory_maps'], key=lambda x: x.rss, reverse=True)
321
        for i, region in enumerate(maps):
322
            if not verbose and i >= NON_VERBOSE_ITERATIONS:
323
                print_("", "[...]")
324
                break
325
            print_("", template % (bytes2human(region.rss), region.path))
326

327

328
def main():
329
    parser = argparse.ArgumentParser(
330
        description="print information about a process"
331
    )
332
    parser.add_argument("pid", type=int, help="process pid", nargs='?')
333
    parser.add_argument(
334
        '--verbose', '-v', action='store_true', help="print more info"
335
    )
336
    args = parser.parse_args()
337
    run(args.pid, args.verbose)
338

339

340
if __name__ == '__main__':
341
    sys.exit(main())
342

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.