grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a ùº†jqcã@sÒdZddlZddlmZmZmZmZmZddlm Z m Z m Z m Z m Z ddlmZmZmZmZmZmZmZmZGdd„deƒZGdd „d eƒZGd d „d e ƒZGd d „d eƒZGdd„deƒZGdd„deeƒZdS)zA Convenience Classes building on the base PMAPI extension module éN)Úc_intÚc_uintÚc_char_pÚcastÚPOINTER)Ú pmContextÚpmValueÚpmDescÚpmErrÚtimeval)ÚPM_CONTEXT_HOSTÚPM_CONTEXT_ARCHIVEÚ PM_INDOM_NULLÚ PM_IN_NULLÚ PM_ID_NULLÚPM_SEM_COUNTERÚ PM_ERR_EOLÚPM_TYPE_DOUBLEc@seZdZdZdd„ZdS)Ú MetricCorea Core metric information that can be queried from the PMAPI PMAPI metrics are unique by name, and MetricCores should be also rarely, some PMAPI metrics with different names might have identical PMIDs PMAPI metrics are unique by (name) and by (name,pmid) - _usually_ by (pmid) too. Note that names here (and only here) are stored as byte strings for direct PMAPI access. All dictionaries/caching strategies built using the core structure use native strings (i.e., not byte strings in python3). cCs<||_t|tƒs| d¡}||_||_d|_d|_d|_dS)Núutf-8) ÚctxÚ isinstanceÚbytesÚencodeÚnameÚpmidÚdescÚtextÚhelp)Úselfrrr©r ú./usr/lib64/python3.9/site-packages/pcp/pmcc.pyÚ__init__+s  zMetricCore.__init__N)Ú__name__Ú __module__Ú __qualname__Ú__doc__r"r r r r!r s rc@sœeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.d/„Zeed0d0d0ƒZeed0d0d0ƒZeed0d0d0ƒZeed0d0d0ƒZee d0d0d0ƒZ ee d0d0d0ƒZ!eeed0d0ƒZ"eed0d0d0ƒZ#eeed0d0ƒZ$eeed0d0ƒZ%eed0d0d0ƒZ&eed0d0d0ƒZ'eed0d0d0ƒZ(eed0d0d0ƒZ)d1d2„Z*d3d4„Z+d0S)5ÚMetriczŽ Additional metric information, such as conversion factors and values several instances of Metric may share a MetricCore instance cCsL||_d|_d|_d|_d|_|jjj|_d|_ d|_ d|_ d|_ d|_ dS©N)Ú_coreÚ_vsetÚ_valuesÚ _prevvsetÚ _prevValuesrÚcontentsÚtypeÚ _convTypeÚ _convUnitsÚ _errorStatusÚ _netValuesÚ_netPrevValuesZ_netConvertedValues)rÚcorer r r!r"?s zMetric.__init__cCs|jjSr()r)r©rr r r!Ú_R_ctxOsz Metric._R_ctxcCs |jj ¡Sr()r)rÚdecoder6r r r!Ú_R_nameQszMetric._R_namecCs|jjSr()r)rr6r r r!Ú_R_pmidSszMetric._R_pmidcCs|jjSr()r)rr6r r r!Ú_R_descUszMetric._R_desccCs|jjSr()r)rr6r r r!Ú_R_textWszMetric._R_textcCs|jjSr()r)rr6r r r!Ú_R_helpYszMetric._R_helpcCst|jjttƒƒ}||S)z% Return the vlist[vlist_idx] of vset )rr.Zvlistrr)rÚvsetÚ vlist_idxZlistptrr r r!Ú get_vlist\szMetric.get_vlistcCs| ||¡jS)z. Return the inst for vlist[vlist_idx] of vset )r@Úinst)rr>r?r r r!Úget_instaszMetric.get_instc CsÐ|}|j}| |jjj¡}g}t|jƒD]¢}| ||¡}z||j}Wnt y\d}Yn0|j  |j ||jj |j ¡} |jr®ttƒdƒ} |j| d<|j |j | | d|j¡} |  |j ¡} | ||| f¡q(|S)zj Extract the value for a singleton or list of instances as a triple (inst, name, val) Úér)rÚ mcGetInstDrr.ÚindomÚrangeÚnumvalr@rAÚKeyErrorÚpmExtractValueÚvalfmtr/r0r1rr Ú pmConvScaleÚdrefÚappend) rZinValuesr>rÚinstDÚvalLÚiÚinstvalrÚoutAtomrÚvaluer r r!Ú computeValueses,     ÿ ÿ zMetric.computeValuescCsV||jkr$| ||¡}||jkr$|St|jƒD]"}| ||¡}||jkr.|Sq.dS)z2 Find a metric instance in the previous resultset N)rHr@rArG)rÚindexrAÚpvsetÚpinstvalZpir r r!Ú_find_previous_instval~s      zMetric._find_previous_instvalc CsV|jjtkr| |¡S|dur"dS|}|}|j}| |jjj¡}g}t|j ƒD�]} |  || ¡} |  | | j |¡} | durzqNz|| j } Wnt yžd} Yn0|j |j| |jjt¡} |j |j| |jjt¡}|j�rttƒdƒ}|j|d<|j t| |d|j¡} |j t||d|j¡}|  t¡}| t¡}||krN| | | |||f¡qN|S)zÊ Extract the value for a singleton or list of instances as a triple (inst, name, val) for COUNTER metrics with the value delta calculation applied (for rate conversion). NrCrDr)rÚsemrrUrrEr.rFrGrHr@rYrArIrJrKr/rr1rr rLrMrN)rÚvaluesÚ prevValuesÚdeltarWr>rrOrPrQrRrXrrSZpoutAtomrrTZpvaluer r r!Ú convertValuesŠsL      ÿ ÿ  ÿ ÿ  zMetric.convertValuescCs|jSr()r+r6r r r!Ú _R_values²szMetric._R_valuescCs|jSr()r-r6r r r!Ú _R_prevValues´szMetric._R_prevValuescCs|jSr(©r0r6r r r!Ú _R_convType¶szMetric._R_convTypecCs|jSr(©r1r6r r r!Ú _R_convUnits¸szMetric._R_convUnitscCs|jSr()r2r6r r r!Ú_R_errorStatus»szMetric._R_errorStatuscCs|jSr()Ú_netConvValuesr6r r r!Ú_R_netConvValues¾szMetric._R_netConvValuescCs|js dS| |j¡|_|jSr()r,rUr4r6r r r!Ú_R_netPrevValuesÁszMetric._R_netPrevValuescCs|js dS| |j¡|_|jSr()r*rUr3r6r r r!Ú _R_netValuesÇszMetric._R_netValuescCs |j|_||_|j|_d|_dSr()r+Ú_prevZ _netValueZ_netPrev)rr[r r r!Ú _W_valuesÍszMetric._W_valuescCs ||_dSr(ra©rrTr r r!Ú _W_convTypeÓszMetric._W_convTypecCs ||_dSr(rcrlr r r!Ú _W_convUnitsÕszMetric._W_convUnitsNcCsN|j |jj¡}tdd|ƒ|j |jj¡}|jD]\}}}td||ƒq2dS)Nz zindom:)rZ pmInDomStrrrFÚprintrEÚ netValues)rZindomstrÚ_rÚvalr r r!Ú metricPrintês  zMetric.metricPrintcCs| |j|j|¡}||_|jSr()r^r*r,rf)rr]Z convertedListr r r!Ú metricConvertñszMetric.metricConvert),r#r$r%r&r"r7r9r:r;r<r=r@rBrUrYr^r_r`rbrdrergrhrirkrmrnÚpropertyrrrrrrr[r\ZconvTypeZ convUnitsZ errorStatusrpZ netPrevValuesZ netConvValuesrsrtr r r r!r'6sP (r'c@sFeZdZdZedfdd„Zdd„Zdd„Zd d „Zd d „Z d d„Z dS)Ú MetricCachea} A cache of MetricCores is kept to reduce calls into the PMAPI library this also slightly reduces the memory footprint of Metric instances that share a common MetricCore a cache of instance domain information is also kept, which further reduces calls into the PMAPI and reduces the memory footprint of Metric objects that share a common instance domain úlocal:cCs0t |||¡i|_i|_i|_d|_d|_dS)Nr)rr"Ú _mcIndomDÚ _mcByNameDÚ _mcByPmidDÚ _mcCounterÚ _mcMetrics©rÚtypedÚtargetr r r!r"s zMetricCache.__init__cCs |j|S)z/ Query the instance : instance_list dictionary )rx)rrFr r r!rEszMetricCache.mcGetInstDcCsè|jjj}||jvr’t|ƒjttƒjkr2tdi}nP|jt krN|  |j¡\}}n|  |j¡\}}|dur~|dur~t t ||ƒƒ}ni}|j ||i¡|jjjtkr®|jd7_|jd7_|j |j ¡|i¡|j |j|i¡dS)z Update the dictionary s PM_IN_NULLNrD)rr.rFrxrrTrrZ_typer ZpmGetInDomArchiveZ pmGetInDomÚdictÚzipÚupdaterZrr{r|ryrr8rzr)rr5rFZinstmapZinstLÚnameLr r r!Ú_mcAdds     zMetricCache._mcAddc CsÀg}d}d}t|ƒD]J\}}t|tƒr.| ¡}|j |¡}|sT|sFi}| ||i¡| |¡q|r¸| |  ¡¡\}}|D]<\}} | t krž|s’g}| |¡qz|  || ¡} | |||<qz||fS)z3 Update the core (metric id, description,...) list N) Ú enumeraterrr8ryÚgetr‚rNÚ mcFetchPmidsÚkeysrÚ _mcCreateCore) rrƒÚcoreLZmissDÚerrLrVrr5ZidLrÚnewcorer r r!ÚmcGetCoresByName+s,      zMetricCache.mcGetCoresByNamec Csxt|||ƒ}z| |¡|_WnLtyh}z4d| ¡| ¡f}tj |¡t dƒ‚WYd}~n d}~00|  |¡|S)z Update the core description z%s: pmLookupDesc: %srDN) rZ pmLookupDescrr ÚprognameÚmessageÚsysÚstderrÚwriteÚ SystemExitr„)rrrrŒÚerrorÚfailr r r!r‰Ns   zMetricCache._mcCreateCorec Csêd}tt|ƒƒ}t|ƒD](\}}t|tƒs6| d¡}t|ƒ||<qzJ| |¡}t|ƒt|ƒkrŒdt|ƒt|ƒf}tj  d|¡t dƒ‚WnLt yÚ}z4d|  ¡|  ¡f} tj  | ¡t dƒ‚WYd}~n d}~00t||ƒ|fS)zD Update the core metric ids. note: some names have identical pmids Nrz%d of %d metric nameszCannot resolve %srDz%s: pmLookupName: %s)rÚlenr…rrrÚ pmLookupNamer�r‘r’r“r rŽr�r�) rrƒr‹ÚnameArVrÚ pmidArrayÚmissingr”r•r r r!r‡\s"     zMetricCache.mcFetchPmidsN) r#r$r%r&r r"rEr„r�r‰r‡r r r r!rv÷s  #rvc@sÞeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z e edddƒZ e edddƒZe edddƒZe ee ddƒZe edddƒZe e dddƒZe e dddƒZgfdd„Zdd„Zdd„Zdd„Zdd„ZdS)Ú MetricGroupaˆ Manages a group of metrics for fetching the values of a MetricGroup is a dictionary of Metric objects, for which data can be fetched from a target system using a single call to pmFetch the Metric objects are indexed by the metric name pmFetch fetches data for a list of pmIDs, so there is also a shadow dictionary keyed by pmID, along with a shadow list of pmIDs cCs|jSr()Ú_ctxr6r r r!Ú_R_contextCacheszMetricGroup._R_contextCachecCs|jj|jjkSr()rœr{r|r6r r r!Ú_R_nonCounters�szMetricGroup._R_nonCounterscCs|jSr()Ú _pmidArrayr6r r r!Ú _R_pmidArrayƒszMetricGroup._R_pmidArraycCs |jjjSr()Ú_resultr.Ú timestampr6r r r!Ú _R_timestamp…szMetricGroup._R_timestampcCs|jSr()r¡r6r r r!Ú _R_result‡szMetricGroup._R_resultcCs |jjjSr()rjr.r¢r6r r r!Ú_R_prevTimestamp‰szMetricGroup._R_prevTimestampcCs|jSr()rjr6r r r!Ú_R_prev‹szMetricGroup._R_prevcCs|j|_||_dSr()r¡rj)rZpmresultr r r!Ú _W_result‘szMetricGroup._W_resultNcCs6t |¡||_d|_d|_d|_i|_| |¡dSr()r€r"rœrŸr¡rjÚ_altDÚmgAdd)rÚ contextCacheÚinLr r r!r"£s zMetricGroup.__init__cCs*||vrtdƒ‚t ||t||d�¡dS©Nz)metric group with that key already exists)r«©rIr€Ú __setitem__r›©rÚattrrTr r r!r®¬szMetricGroup.__setitem__c Cs†|j |¡\}}|D].}t|ƒ}| |j|i¡|j |j|i¡qt|ƒ}t|ƒ|_ t |  ¡ƒD]\}}t||jƒ|j |<qddS)z Create the list of Metric(s) N) rœr�r'r‚rr¨rr–rrŸr…rˆ) rrƒrŠrqr5ZmetricÚnÚxÚkeyr r r!r©´s zMetricGroup.mgAddc CsÖzl|j |j¡|_|jj}t|jjjƒD]@}|jj |¡}|jj |¡}|j |j |j |_ ||j |_ q(Wnbt yÎ}zJ|j dtkr’tdƒ‚d| ¡| ¡f}tj |¡tdƒ‚WYd}~n d}~00|jS)zl Fetch the list of Metric values. Save the old value. Return the result timestamp. rz%s: pmFetch: %srDN)rœZpmFetchrŸÚresultr.rGZnumpmidZget_pmidZget_vsetr¨r*r,r Úargsrr“rŽr�r�r‘r’r¢)rr´rQrr>r”r•r r r!ÚmgFetchÀs zMetricGroup.mgFetchcCs(|jdurt|jƒ}nd}t|jƒ|S)z‚ Sample delta - used for rate conversion calculations, which requires timestamps from successive samples. Nç)rjÚfloatÚ prevTimestampr¢)rr¹r r r!ÚmgDelta×s  zMetricGroup.mgDelta)r#r$r%r&r�ržr r£r¤r¥r¦r§rurªÚ nonCountersr™r´r¢Úprevr¹r"r®r©r¶rºr r r r!r›rs*   r›c@s eZdZdZdd„Zdd„ZdS)ÚMetricGroupPrintera Handles reporting of MetricGroups within a GroupManager. This object is called upon at the end of each fetch when new values are available. It is also responsible for producing any initial (or on-going) header information that the tool may wish to report. cCs4| ¡D]&}||}| ¡D]}|| ¡qqdS)z0 Base implementation, all tools should override N)rˆrs)rÚmanagerÚ group_nameÚgroupÚ metric_namer r r!Úreportës  zMetricGroupPrinter.reportcCs>| ¡D]0}||}| ¡}| ¡D]}|| |¡q$qdS)z1 Do conversion for all metrics across all groups N)rˆrºrt)rr¾r¿rÀr]rÁr r r!Úconvertòs   zMetricGroupPrinter.convertN)r#r$r%r&rÂrÃr r r r!r½ãsr½c@sèeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z e eeddƒZ e eeddƒZe ee ddƒZe de ddƒZe e dddƒZedfdd„Zdd„Zedd„ƒZdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„ZdS)&ÚMetricGroupManagerzƒ Manages a dictionary of MetricGroups which can be pmFetch'ed inherits from MetricCache, which inherits from pmContext cCs|jSr(©Ú_optionsr6r r r!Ú _R_optionsszMetricGroupManager._R_optionscCs ||_dSr(rÅ)rÚoptionsr r r!Ú _W_optionsszMetricGroupManager._W_optionscCs|jSr(©Ú_default_deltar6r r r!Ú_R_default_delta sz#MetricGroupManager._R_default_deltacCs ||_dSr(rÊ)rr]r r r!Ú_W_default_delta sz#MetricGroupManager._W_default_deltacCs|jSr(©Ú_default_pauser6r r r!Ú_R_default_pausesz#MetricGroupManager._R_default_pausecCs ||_dSr(rΩrÚpauser r r!Ú_W_default_pausesz#MetricGroupManager._W_default_pausecCs ||_dSr()Ú_printer)rÚprinterr r r!Ú _W_printerszMetricGroupManager._W_printercCs|jSr()Ú_counterr6r r r!Ú _R_counterszMetricGroupManager._R_counterNrwcCs@t |¡t |||¡d|_tddƒ|_d|_d|_d|_dS)NrDr) r€r"rvrÆr rËrÏrÔr×r}r r r!r"%s  zMetricGroupManager.__init__cCs*||vrtdƒ‚t ||t||d�¡dSr¬r­r¯r r r!r®.szMetricGroupManager.__setitem__cCs$| ||¡}t|jdƒ|_||_|S)z8 Helper interface, simple PCP monitor argument parsing. r)Z fromOptionsr r]rËrÆ)ÚclsrÈÚargvr¾r r r!Úbuilder3s zMetricGroupManager.buildercCs$|dur dSt|jƒt|jƒdS)z- convert timeval to epoch seconds as a float Nr·g€„.A)r¸Ztv_secZtv_usec)rZtvr r r!Ú _tv2float>szMetricGroupManager._tv2floatc CsÀ|jdurdSd}| ¡D]}||jrd}q|j ¡}|durL||dfS|j ¡dur^dS|j ¡}|j ¡}|j ¡}|durŠ|j}|  |¡}|  |¡|  |¡|}t |dƒ||fS)a Return the number of samples we are to take and the finish time, or 0,0 if --finish is not specified. This is based on command line options --samples but also must consider --start, --finish and --interval. If none of these were presented, a zero return means "infinite". Also consider whether the utility needs rate-conversion, automatically increasing the sample count to accommodate when counters metrics are present. N)rNrDrgà?) rÆrˆr»ZpmGetOptionSamplesZpmGetOptionFinishOptargZpmGetOptionOriginZpmGetOptionFinishÚpmGetOptionIntervalrËrÜÚint) rZextrarÀÚsamplesÚoriginÚfinishr]ZperiodZwindowr r r!Ú_computeSamplesDs&         z"MetricGroupManager._computeSamplescCsd|jdur|jS|jtkr(tddƒ|_n6|jdurV|j ¡}|durL||_q^|j|_n|j|_|jS)aV Figure out how long to sleep between samples. This needs to take into account whether we were explicitly asked for a delay (independent of context type, --pause), whether this is an archive or live context, and the sampling --interval (including the default value, if none requested). Nr)rÏr/r r rÆrÝrËrÑr r r!Ú_computePauseTimecs     z$MetricGroupManager._computePauseTimec Cs¸g}tt|ƒƒ}t|ƒD](\}}t|tƒs6| d¡}t|ƒ||<qzt ||¡WnVtyªt|ƒD]:\}}zt ||¡Wqjty¢|  ||¡Yqj0qjYn0|s´dS|S)zÝ Return a list of metrics that are missing from the default context. This is usually only applicable when replaying archives. Return None if all found, else a list of missing metric names. rN) rr–r…rrrrr—r rN)rrƒršr˜rQr±r r r!ÚcheckMissingMetricsxs"    z&MetricGroupManager.checkMissingMetricscCsJd}d}| ¡D]4}|| ¡}|dus6| |¡|kr|}| |¡}q|S)z/ Perform fetch operation on all of the groups. Nr·)rˆr¶rÜ)rZ fetchtimeZrmaxrÀZstampr r r!Úfetch’s   zMetricGroupManager.fetchc CsÄ| ¡\}}| ¡}zr| ¡}|j|kr4dkr:q„nq„|durX| |¡| |¡krXq„|j |¡| ¡| ¡}|jd7_qWn8ty®}z|WYd}~Sd}~0t y¾Yn0dS)av Using options specification, loop fetching and reporting, pausing for the requested time interval between updates. Transparently handles archive/live mode differences. Note that this can be different to the sampling interval in archive mode, but is usually the same as the sampling interval in live mode. rNrD) rârãrår×rÜrÔrÂÚsleepr“ÚKeyboardInterrupt)rrßráZtimerZcurtimeÚcoder r r!Úrun�s"   zMetricGroupManager.run)r#r$r%r&rÇrÉrÌrÍrÐrÓrÖrØrurÈZ default_deltaZ default_pauserÕZcounterr r"r®Ú classmethodrÛrÜrârãrärårér r r r!rÄûs0   rÄ)r&r�ZctypesrrrrrZ pcp.pmapirrr r r Zcpmapir r rrrrrrÚobjectrr'rvr€r›r½rÄr r r r!Ús(B{q