3 bfZ< @sddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ej j dZyddlmZeZWndZYnXdZe se reded esed esed ejd dd lmZmZddlmZmZmZmZddlmZmZGddde Z!Gddde!Z"d Z#d Z$dZ%d Z&dZ'Gddde Z(ddZ)ddZ*ddZ+Gddde!Z,Gd d!d!e!Z-Gd"d#d#e!Z.d$d%Z/dS)&)print_functionN)cmdlinez /proc/self/io)VmStatFTz= 2.6.20 withz~ - I/O accounting support (CONFIG_TASKSTATS, CONFIG_TASK_DELAY_ACCT, CONFIG_TASK_IO_ACCOUNTING, kernel.task_delayacct sysctl)z0 - VM event counters (CONFIG_VM_EVENT_COUNTERS))iopriovmstat) ConnectionNETLINK_GENERICU32Attr NLM_F_REQUEST) Controller GeNlMessagec@seZdZdZddZdS)DumpableObjectzFBase class for all objects that allows easy introspection when printedcCs$dtt|ddtj|jfS)Nz%s: %s>r)strtypepprintZpformat__dict__)selfr/usr/lib/python3.6/data.py__repr__?szDumpableObject.__repr__N)__name__ __module__ __qualname____doc__rrrrrr=src@sLeZdZdddddgZd Zd d ZdddZddZddZe ddZ d S)Statsblkio_delay_total(swapin_delay_total8 read_bytes write_bytescancelled_write_bytesNcCsP|j}x6tjD],\}}|||d}tjd|d||<qWtjsLtt_dS)NQr)rrmembers_offsetsstructunpackhas_blkio_delay_totalsysctl_task_delayacct)rZtask_stats_buffersdnameoffsetdatarrr__init__Rs zStats.__init__rc CsB|j}|j}|j}x*tjD] \}}|||||||<qWdS)z3Update destination from operator(self, other_stats)N)rrr)) r other_stats destinationcoeffZddr.Zodmemberr0rrr accumulate]s zStats.accumulatecCs|j||ddS)z*Update destination with self - other_statsr)r5r)r7)rr3r4rrrdeltaesz Stats.deltacCs.|j}x"tjD]\}}||dkrdSqWdS)NrFT)rrr))rr.r/r0rrr is_all_zerois  zStats.is_all_zerocCs0tjt}|j}xtjD]\}}d||<qW|S)Nr)r__new__rr))statsZstdr/r0rrrbuild_all_zerops   zStats.build_all_zero)rr)rr )r!r")r#r$)r%r&)r) rrrr)r,r2r7r8r9 staticmethodr<rrrrrGs rc@s$eZdZddZddZddZdS)TaskStatsNetlinkcCs*||_tt|_t|j}|jd|_dS)NZ TASKSTATS)optionsrr connectionr Z get_family_id family_id)rrAZ controllerrrrr2s  zTaskStatsNetlink.__init__cCst|jttt|gtdS)N)cmdattrsflags)r rCTASKSTATS_CMD_GETr TASKSTATS_CMD_ATTR_PIDr )rtidrrr build_requests zTaskStatsNetlink.build_requestcCs|jj|jytj|j}Wn4tk rR}z|jtjkr@dSWYdd}~XnXx,|jj D]\}}|t kr`|j }Pq`WdS|t j }t|dkrdStjd|ddd}|dkstt|S)NiHrr>)task_stats_requestsendrBr ZrecvOSErrorerrnoZESRCHrEitemsTASKSTATS_TYPE_AGGR_PIDnestedTASKSTATS_TYPE_STATSr1lenr*r+AssertionErrorr)rthreadZreplyeZ attr_typeZ attr_valueZtaskstats_dataZtaskstats_versionrrrget_single_task_statss$    z&TaskStatsNetlink.get_single_task_statsN)rrrr2rJrYrrrrr@sr@cCsg|_d}x|jpgD]t}y t|}WnRtk rxytj|}Wn(tk rltd|tj dd}YnX|j }YnX|s|jj |qW|rtj ddS)zDBuild options.uids from options.users by resolving usernames to UIDsFz Unknown user:)fileTrN) uidsZusersint ValueErrorpwdgetpwnamKeyErrorprintsysstderrZpw_uidappendexit)rAerroruuidZpasswdrrr find_uidss    ric CsTi}y6x0td|D] }|jdd\}}|j||<qWWntk rNYnX|S)Nz/proc/%d/statusz: r)opensplitstripIOError)pidZ result_dictlinekeyvaluerrrparse_proc_pid_statussrrc Cs<y |jdStk r$|jdStk r6|SXdS)Nzutf-8Z string_escape)decodeUnicodeDecodeErrorencodeAttributeError)srrrsafe_utf8_decodes   rxc@s0eZdZdZddZddZddZdd Zd S) ThreadInfozStats for a single threadcCs.||_d|_d|_tjt|_|j||_dS)NT)rImark stats_totalrr: stats_deltarJrM)rrItaskstats_connectionrrrr2s  zThreadInfo.__init__cCs tj|jS)N)rgetrI)rrrr get_ioprioszThreadInfo.get_iopriocCstjtj|j||S)N)r set_ioprioZIOPRIO_WHO_PROCESSrI)r ioprio_class ioprio_datarrrrs zThreadInfo.set_iopriocCs&|js ||_|j|j|j||_dS)N)r{r8r|)rr;rrr update_statsszThreadInfo.update_statsN)rrrrr2rrrrrrrrys ryc@sheZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZdS) ProcessInfozStats for a single process (a single line in the output): if options.processes is set, it is a collection of threads, otherwise a single thread.cCs:||_d|_d|_i|_tj|_tj|_tj|_ dS)N) rnrhuserthreadsrr<r| stats_accumtimeZstats_accum_timestamp)rrnrrrr2s  zProcessInfo.__init__cCs:|jr|j r|j|jkrdS|jr6|j|jkr6dSdS)NFT)pids processesrnr[get_uid)rrArrr is_monitoreds  zProcessInfo.is_monitoredc CsZ|jr |jSytjd|jtj}Wntk r>d}YnX||jkrVd|_||_|S)Nz/proc/%d)rhosstatrnST_UIDrOr)rrhrrrrs  zProcessInfo.get_uidc Cs\|j}|dk rR|j rRyttj|j|_Wn"ttfk rPt||_YnX|jpZdS)Nz{none}) rrrxr^getpwuidZpw_namer`rvr)rrhrrrget_userszProcessInfo.get_userc Cs ytd|j}|jd}Wntk r0dSXt|j}|sb|jdd}|rZd|}nd}|Sd}t|jd|j}||jkrt|jdd}|jdd}||kr|d |7}|jd } | d jd r| d j d d } | d | d| d <dj | j }t ||S)Nz/proc/%d/cmdlineiz{no such process}Namez[%s]z {no name}ZTgidz [%s]r/r ) rjrnreadrmrrr~r\rk startswithrfindjoinrlrx) rZ proc_cmdlinerZ proc_statusZproc_status_namesuffixtgidZ tgid_nameZ thread_namepartsZfirst_command_charrrr get_cmdlines2       zProcessInfo.get_cmdlinecCs6|r|jj Sx |jjD]}|jjsdSqWdS)NTF)rr9rvaluesr|)rZ accumulatedtrrr did_some_io<s   zProcessInfo.did_some_iocCs0tdd|jjD}t|dkr,|jSdS)Ncss|]}|jVqdS)N)r).0rrrr Esz)ProcessInfo.get_ioprio..rz?dif)setrrrUpop)rZ prioritiesrrrrDs zProcessInfo.get_iopriocCs$x|jjD]}|j||q WdS)N)rrr)rrrrWrrrrJszProcessInfo.set_iopriocCstj|jS)N)rZsort_keyr)rrrrioprio_sort_keyNszProcessInfo.ioprio_sort_keycCs*|jj|d}|s&t||}||j|<|S)N)rr~ry)rrIr}rWrrr get_threadQs   zProcessInfo.get_threadcCstj}x*|jjD]\}}|js|j|j|qWtdd|jjD|_t|j}|s`dS|j |_ |j |_ ||_|j j|j|j dS)NcSsg|]\}}|js||fqSr)rz)rrIrWrrr ]sz,ProcessInfo.update_stats..FT) rr<rrQrzr7r|dictrUrrr)rr|rIrWZ nr_threadsrrrrXs zProcessInfo.update_statsN)rrrrr2rrrrrrrrrrrrrrrs   rc@sDeZdZddZddZddZddZd d Zd d Zd dZ dS) ProcessListcCs2i|_||_||_tj|_tj|_|jdS)N)rr}rAr timestamprrupdate_process_counts)rr}rArrrr2ms   zProcessList.__init__cCs8|jj|d}|s$t|}||j|<|j|jr4|SdS)zyEither get the specified PID from self.processes or build a new ProcessInfo if we see this PID for the first timeN)rr~rrrA)rrnprocessrrr get_processxs   zProcessList.get_processc Cs|jjr|jjStjd}|jjr0dd|DSg}x`|D]X}d|dkoTdknr:y"|jtttjd|dWq:tk rYq:Xq:W|S) Nz/proccSs0g|](}d|dkodknrt|qS)0r9)r\)rrrrrrsz*ProcessList.list_tgids..rrrz/proc/z/task) rArrlistdirrextendmapr\rO)rZtgidstidsrrrr list_tgidss  " zProcessList.list_tgidsc Csf|jjs|gSyttttjd|}Wntk r>gSX|jjrbtt |jjj t |}|S)Nz /proc/%d/task) rArlistrr\rrrOrr intersection)rrrrrr list_tidsszProcessList.list_tidsc Cstj}||j|_||_d}}x||jD]p}|j|}|s@q,xZ|j|D]L}|j||j}|jj|}|rL|j ||j } || j 7}|| j 7}d|_ qLWq,W||f|jjfS)NrF)rrZdurationrrrrr}rYrr|r!r#rzrr8) rZ new_timestampZ total_readZ total_writerrrIrWr;r8rrrrs$      z!ProcessList.update_process_countscCsTx,|jjD]}x|jjD] }d|_qWq W|j}tdd|jjD|_|S)NTcSs g|]\}}|jr||fqSr)r)rrnrrrrrsz1ProcessList.refresh_processes..)rrrrzrrrQ)rrrWZtotal_read_and_writerrrrefresh_processesszProcessList.refresh_processescCs i|_dS)N)r)rrrrclearszProcessList.clearN) rrrr2rrrrrrrrrrrls   rcCsdtjkS)a| WAS: try: with open('/proc/sys/kernel/task_delayacct') as f: return bool(int(f.read().strip())) except FileNotFoundError: return None Because /proc/sys/kernel/task_delayacct doesn't exist on RHEL8, it always returns None, which is equivalent to False in the end. On RHEL8, delayacct_on kernel variable is enabled by default Z nodelayacct)rkeysrrrrr-sr-)0Z __future__rrPrrr^rr*rbrZprocfsrpathexistsZ ioaccountingZ iotop.vmstatrZvmstat_fZvm_event_countersrareZiotoprrZ iotop.netlinkrr r r Ziotop.genetlinkr r objectrrrGrHrRZTASKSTATS_TYPE_PIDrTr@rirrrxryrrr-rrrrsV         5) ^