o
     bN                    @   sp  d Z ddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl	m
Z
mZmZmZmZmZ ddl	mZmZmZmZmZmZ ddl	mZmZmZmZmZ ddl	mZmZmZmZmZ ddl m!Z! ee!dZ"ej#d	krqd
ndZ$ee!e$Z%ej&dkre'fZ(e'Z)e*Z+ne'e)fZ(e,Z+dd Z-G dd de.Z/G dd de.Z0ej1dkreZ2nej1dkreZ2ne/ej3dej4dkreZ5nej4dkreZ5ne/ej3dG dd deZ6G dd deZ7G dd deZ8G dd deZ9G dd  d eZ:G d!d" d"eZ;G d#d$ d$eZ<G d%d& d&eZ=G d'd( d(eZ>ee>Z?e@d)d* ddde?_Ae@d+d* ddde?_Be@d,d* ddde?_Ce@d-d* ddde?_DG d.d/ d/eZEeZFeZGG d0d1 d1eZHeeHZIe@d2d* dddeI_Je@d3d* dddeI_Ke@d4d* dddeI_Le@d5d* dddeI_Md6d7 ZNG d8d9 d9eZOG d:d; d;eZPG d<d= d=eZQeeQZRe@d>d* dddeR_Se@d?d* dddeR_Te@d@d* dddeR_Ue@dAd* dddeR_Ve@dBd* dddeR_WG dCdD dDeZXee"jY_Zeeeege"jY_[ee"j\_Zeeeeeeege"j\_[ee"j]_Zg e"j]_[ee"j^_Zege"j^_[ee"j__ZeedE eege"j__[ee"j`_Zeeeege"j`_[ee"ja_Zeeege"ja_[edeZbee"jc_Zeebge"jc_[ee"jd_Zg e"jd_[ee"je_Zeeeege"je_[ee"jf_Zege"jf_[ee"jg_ZeeeHge"jg_[ee"jh_ZeeeeeHge"jh_[ee"ji_Zeeeege"ji_[ee"jj_Zeeeege"jj_[ee"jk_Zeeeeeeege"jk_[ee"jl_Zeege"jl_[ee"jm_Zeeeege"jm_[ee"jn_Zeege"jn_[ee"jo_Zege"jo_[ee"jp_Zg e"jp_[ee"jq_Zege"jq_[ee"jr_Zg e"jr_[ee"js_Zeeeege"js_[ee"jt_Zeeeege"jt_[ee"ju_Zeee6ege"ju_[ee"jv_Zege"jv_[ee"jw_Zeeege"jw_[ee"jx_Zg e"jx_[ee"jy_Zege"jy_[ee"jz_Zege"jz_[ee"j{_Zeege"j{_[ee8e"j|_Zeeee8ge"j|_[ee"j}_Zeeege"j}_[ee"j~_ZeeeeeeEge"j~_[de"j_ZeeEge"j_[ee"j_ZeeEge"j_[ee"j_ZeePge"j_[ee"j_Zee6ge"j_[ee"j_Zeeeeeeege"j_[ee"j_Zeege"jl_[eGege"j_[ee"j_ZeGege"j_[ee"j_ZeeeEge"j_[ee"j_Zege"j_[ee"j_Zeeege"j_[ee"j_Zeee=eee9ege"j_[ee"j_Zeee9ee:ee9ee:ge"j_[ee"j_Zee:eege"j_[ee"j_Zeeege"j_[ee"j_Zeeege"j_[ee"j_Zege"j_[ee"j_Zege"j_[ee"j_Zege"j_[ee"j_Zeeege"j_[ee"j_Zeege"j_[ee"j_Zege"j_[ee"j_Zege"j_[ee"j_Zeeege"j_[ee"j_Zeeege"j_[ee"j_Zee9eeege"j_[ee"j_Zeeege"j_[de"j_Zeeeee=ege"j_[ee"j_Zeee6eege"j_[ee"j_ZeeeeeeOeege"j_[ee"j_Zg e"j_[ee"j_Zege"j_[de"j_ZeeEge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeeXge"j_[ee"j_ZeeeXge"j_[ee"j_Zeeeeege"j_[eeeeQeeZee"j_ZeeeXeeeeege"j_[de"j_ZeeXege"j_[G dFdG dGeZG dHdI dIeZee"j_Zeeeege"j_[ee"j_Zege"j_[ee"j_Zege"j_[ee"j_Zege"j_[ee"j_Zeeeeee9eeege"j_[ee"j_Zeeeeeeeee9eeeeeeeege"j_[ee"j_Zeeeeeee7ee9eeeeeeeege"j_[ee"j_Zeee6ge"j_[ee"j_Zege"j_[G dJdK dKeZdS )La   Wrapper module for LIBPCP - the core Performace Co-Pilot API
#
# Copyright (C) 2012-2021 Red Hat
# Copyright (C) 2009-2012 Michael T. Werner
#
# This file is part of the "pcp" module, the python interfaces for the
# Performance Co-Pilot toolkit.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#

# Additional Information:
#
# Performance Co-Pilot Web Site
# https://pcp.io
#
# Performance Co-Pilot Programmer's Guide
# cf. Chapter 3. PMAPI - The Performance Metrics API
#
# EXAMPLE

    from pcp import pmapi
    import cpmapi as c_api

    # Create a pcp class
    context = pmapi.pmContext(c_api.PM_CONTEXT_HOST, "local:")

    # Get ids for number cpus and load metrics
    metric_ids = context.pmLookupName(("hinv.ncpu","kernel.all.load"))
    # Get the description of the metrics
    descs = context.pmLookupDescs(metric_ids)
    # Fetch the current value for number cpus
    results = context.pmFetch(metric_ids)
    # Extract the value into a scalar value
    atom = context.pmExtractValue(results.contents.get_valfmt(0),
                                  results.contents.get_vlist(0, 0),
                                  descs[0].contents.type,
                                  c_api.PM_TYPE_U32)
    print "#cpus=", atom.ul

    # Get the instance ids for kernel.all.load
    inst1 = context.pmLookupInDom(descs[1], "1 minute")
    inst5 = context.pmLookupInDom(descs[1], "5 minute")

    # Loop through the metric ids
    for i in range(results.contents.numpmid):
        # Is this the kernel.all.load id?
        if (results.contents.get_pmid(i) != metric_ids[1]):
            continue
        # Extract the kernel.all.load instance
        for j in range(results.contents.get_numval(i) - 1):
            atom = context.pmExtractValue(results.contents.get_valfmt(i),
                                          results.contents.get_vlist(i, j),
                                          descs[i].contents.type,
                                          c_api.PM_TYPE_FLOAT)
            value = atom.f
            if results.contents.get_inst(i, j) == inst1:
                print "load average 1=",atom.f
            elif results.contents.get_inst(i, j) == inst5:
                print "load average 5=",atom.f


    # ... or, using the fetchgroup interface:

    from pcp import pmapi
    import cpmapi as c_api

    pmfg = pmapi.fetchgroup(c_api.PM_CONTEXT_HOST, "local:")
    v = pmfg.extend_item("hinv.ncpu")
    vv = pmfg.extend_indom("kernel.all.load", c_api.PM_TYPE_FLOAT)
    vvv = pmfg.extend_event("systemd.journal.records", field="systemd.journal.field.string")
    t = pmfg.extend_timestamp()

    pmfg.fetch()
    print("time: %s" % t())
    print("number of cpus: %d" % v())
    for icode, iname, value in vv():
        print("load average %s: %f" % (iname, value()))
    for ts, line in vvv():
        print("%s : %s" % (ts, line()))
    N)c_charc_intc_uintc_longc_char_pc_void_p)c_floatc_doublec_int32c_uint32c_int64c_uint64)CDLLPOINTER	CFUNCTYPE	StructureUnion)	addressofpointersizeofcastbyref)find_librarypcpwin32cmsvcrt3c                 C   s^   t jdkrttjj_tjgtjj_t	j
tj| dddS ttjj_tjgtjj_tj| S )Nr   rF)closefd)sysversionr   ctypes	pythonapiPyObject_AsFileDescriptorrestype	py_objectargtypesosfdopenr   PyFile_AsFile)fileObj r,   +/usr/lib/python3/dist-packages/pcp/pmapi.pypyFileToCFile   s   


r.   c                       s<   e Zd Z fddZdd Zdd Zdd Zd	d
 Z  ZS )pmErrc                    sD   t t| j|  t|| _|rt|d tr|d | _d S d| _d S Nr   )superr/   __init__listargs
isinstanceintcodeselfr4   	__class__r,   r-   r2      s
   

zpmErr.__init__c                 C   sH   d }zt j| j }W n	 ty   Y nw |d u r|  S d||  f S )Nz%s %s)c_apipmErrSymDictr7   KeyErrormessage)r9   errSymr,   r,   r-   __str__   s   zpmErr.__str__c                 C   sZ   t tj}t| j|tj}t| }t	dt
| jD ]}|dt| j|  7 }q|S )N    )r"   create_string_bufferr<   PM_MAXERRMSGLENLIBPCP
pmErrStr_rr7   strdecoderangelenr4   )r9   errStrresultindexr,   r,   r-   r?      s   zpmErr.messagec                 C      t ttdj S N
pmPrognamerH   r   in_dllrF   valuerI   r9   r,   r,   r-   progname   s   zpmErr.prognamec                 C      | j S N)r7   rU   r,   r,   r-   errno      zpmErr.errno)	__name__
__module____qualname__r2   rA   r?   rV   rY   __classcell__r,   r,   r:   r-   r/      s    
r/   c                       s$   e Zd Z fddZdd Z  ZS )
pmUsageErrc                    s   t t| j|  t|| _d S rX   )r1   r_   r2   r3   r4   r8   r:   r,   r-   r2      s   zpmUsageErr.__init__c                 C   s8   t dt| jD ]}tt| j| d qt S )Nr   utf-8)	rJ   rK   r4   rF   pmprintfrH   encoder<   pmUsageMessage)r9   rN   r,   r,   r-   r?      s   zpmUsageErr.message)r[   r\   r]   r2   r?   r^   r,   r,   r:   r-   r_      s    r_         zUnexpected suseconds_t sizezUnexpected time_t sizec                   @   sj   e Zd ZdefdefgZdddZedd Zdd	 Z	d
d Z
dd Zdd Zdd Zdd Zdd ZdS )timevaltv_sectv_usecr   c                 C      t |  || _|| _d S rX   )r   r2   rg   rh   )r9   secusecr,   r,   r-   r2         

ztimeval.__init__c                 C   sL   |  }t  }t|ts|d}t|t|t|}|dk r$t|||S )z7 Construct timeval from a string using pmParseInterval r`   r   )r   r5   bytesrb   rF   pmParseIntervalr   r/   )clsintervaltvperrmsgstatusr,   r,   r-   fromInterval   s   


ztimeval.fromIntervalc                 C   s   dt | j| j S )N%.3f)r<   pmtimevalToRealrg   rh   rU   r,   r,   r-   rA         ztimeval.__str__c                 C      t t| j| jS rX   )floatr<   rv   rg   rh   rU   r,   r,   r-   	__float__   rw   ztimeval.__float__c                 C   rx   rX   )complexr<   rv   rg   rh   rU   r,   r,   r-   __complex__   rw   ztimeval.__complex__c                 C   
   t | jS rX   r6   rg   rU   r,   r,   r-   	__index__      
ztimeval.__index__c                 C   r}   rX   )longrg   rU   r,   r,   r-   __long__  r   ztimeval.__long__c                 C   r}   rX   r~   rU   r,   r,   r-   __int__  r   ztimeval.__int__c                 C   s   t t|  dS )z9 Delay for the amount of time specified by this timeval. N)timesleepry   rU   r,   r,   r-   r   	  s   ztimeval.sleepNr   r   )r[   r\   r]   c_time_tc_suseconds_t_fields_r2   classmethodrt   rA   rz   r|   r   r   r   r   r,   r,   r,   r-   rf      s    

rf   c                   @   s.   e Zd ZdefdefgZd	ddZdd ZdS )
timespecrg   tv_nsecr   c                 C   ri   rX   )r   r2   rg   r   )r9   rj   nsecr,   r,   r-   r2     rl   ztimespec.__init__c                 C   s   dt | jt | jd   S )Nru   g    eA)ry   rg   r   rU   r,   r,   r-   rA     s   ztimespec.__str__Nr   )r[   r\   r]   r   r   r   r2   rA   r,   r,   r,   r-   r     s    
r   c                   @   sb   e Zd Zdefdefdefdefdefdefdefdefd	efd
efdefgZdd Zdd ZdS )tmtm_sectm_mintm_hourtm_mdaytm_montm_yeartm_wdaytm_ydaytm_isdst	tm_gmtofftm_zonec              	   C   sR   | j d }|dk rd}| jd | jd | j| j| j| j|| jd | jg	}t	
|S )NrB   r      l  )r   r   r   r   r   r   r   r   r   r   struct_time)r9   pywdaystlistr,   r,   r-   r   &  s   

ztm.struct_timec                 C   st   t d}t| j| j| j| j| j| j	| j
| j| jt| jt| j}tt|}tt|| t|j  S )N    )r"   rD   r<   pmMktimer   r   r   r   r   r   r   r   r   r   r   rH   r   r   rF   pmCtimer   rT   rI   rstrip)r9   rM   secondtimetpr,   r,   r-   rA   1  s   
z
tm.__str__N)	r[   r\   r]   r   r   r   r   r   rA   r,   r,   r,   r-   r     s    r   c                   @   s   e Zd ZdZdefdefdefdefdefde	fde
fd	efgZejd
d ejdd ejdd ejdd ejdd ejdd ejdd ejdd ejdd ejdd ejdd ejdd ejdd iZdd ZdS )pmAtomValuezUnion used for unpacking metric values according to type

    Constants for specifying metric types are defined in module pmapi
    lulllullfdcpvpc                 C   rW   rX   )r   xr,   r,   r-   <lambda>P      zpmAtomValue.<lambda>c                 C   rW   rX   )r   r   r,   r,   r-   r   Q  r   c                 C   rW   rX   )r   r   r,   r,   r-   r   R  r   c                 C   rW   rX   )r   r   r,   r,   r-   r   S  r   c                 C   rW   rX   )r   r   r,   r,   r-   r   T  r   c                 C   rW   rX   )r   r   r,   r,   r-   r   U  r   c                 C   rW   rX   )r   r   r,   r,   r-   r   V  r   c                 C      d S rX   r,   r   r,   r,   r-   r   W      c                 C   r   rX   r,   r   r,   r,   r-   r   X  r   c                 C   r   rX   r,   r   r,   r,   r-   r   Y  r   c                 C   r   rX   r,   r   r,   r,   r-   r   Z  r   c                 C   r   rX   r,   r   r,   r,   r-   r   [  r   c                 C   r   rX   r,   r   r,   r,   r-   r   \  r   c                 C   sN   | j | | }|tjkr%z
t|d}W |S  ty$   t|}Y |S w |S )Nr`   )
_atomDrefDr<   PM_TYPE_STRINGrH   rI   	Exception)r9   typedrT   r,   r,   r-   dref_  s   

zpmAtomValue.drefN)r[   r\   r]   __doc__r
   r   r   r   r   r	   r   r   r   r<   
PM_TYPE_32PM_TYPE_U32
PM_TYPE_64PM_TYPE_U64PM_TYPE_FLOATPM_TYPE_DOUBLEr   PM_TYPE_AGGREGATEPM_TYPE_AGGREGATE_STATICPM_TYPE_EVENTPM_TYPE_HIGHRES_EVENTPM_TYPE_NOSUPPORTPM_TYPE_UNKNOWNr   r   r,   r,   r,   r-   r   B  s4    
	











r   c                	   @   s   e Zd ZdZejr(dedfdedfdedfdedfdedfdedfd	ed
fgZnd	ed
fdedfdedfdedfdedfdedfdedfgZdddZdd Z	dd Z
dS )pmUnitsz
    Compiler-specific bitfields specifying scale and dimension of metric values
    Constants for specifying metric units are defined in module pmapi
    IRIX => HAVE_BITFIELDS_LTOR, gcc => not so much
    dimSpacerd   dimTimedimCount
scaleSpace	scaleTime
scaleCountpadre   r   c                 C   s8   t |  || _|| _|| _|| _|| _|| _d| _d S r0   )	r   r2   r   r   r   r   r   r   r   )r9   dimSdimTdimCscaleSscaleTscaleCr,   r,   r-   r2     s   

zpmUnits.__init__c                 C   s    t | j| j| j| j| j| jS rX   )r<   pmUnits_intr   r   r   r   r   r   rU   r,   r,   r-   r     s   zpmUnits.__int__c                 C   $   t d}t| |d}t| S )N@   r"   rD   rF   pmUnitsStr_rrH   rI   )r9   unitstrrM   r,   r,   r-   rA     s   
zpmUnits.__str__N)r   r   r   r   r   r   )r[   r\   r]   r   r<   HAVE_BITFIELDS_LTORr   r   r2   r   rA   r,   r,   r,   r-   r   h  s,    

r   c                   @   sV   e Zd ZdZejrdedfdedfded fgZdS dedfdedfded fgZdS )	pmValueBlockzValue block bitfields for different compilers
       A value block holds the value of an instance of a metric
       pointed to by the pmValue structure, when that value is
       too large (> 32 bits) to fit in the pmValue structure
    vtypere   vlen   vbufrB   N)	r[   r\   r]   r   r<   r   r   r   r   r,   r,   r,   r-   r     s    

r   c                   @   s,   e Zd ZdZdeefdefgZdd ZdS )	valueDrefzUnion in pmValue for dereferencing the value of an instance of a metric

    For small items, e.g. a 32-bit number, the union contains the actual value
    For large items, e.g. a text string, the union points to a pmValueBlock
    pvallvalc                 C   s
   d| j  S )Nz
value=%#lx)r   rU   r,   r,   r-   rA     r   zvalueDref.__str__N)	r[   r\   r]   r   r   r   r   r   rA   r,   r,   r,   r-   r     s    
r   c                   @   s(   e Zd ZdZdefdefgZdd ZdS )pmValuez1Structure holding the value of a metric instance instrT   c                 C   s    t | j}dt| | jf | S )NzpmValue@%#lx inst=%d )rH   rT   r   r   )r9   vstrr,   r,   r-   rA     s   
zpmValue.__str__N)r[   r\   r]   r   r   r   r   rA   r,   r,   r,   r-   r     s    r   c                   @   sN   e Zd ZdZdefdefdefded fgZdd Zd	d
 Z	e
e	dddZdS )
pmValueSeta  Structure holding a metric's list of instance values

    A performance metric may contain one or more instance values, one for each
    item that the metric concerns. For example, a metric measuring filesystem
    free space would contain one instance value for each filesystem that exists
    on the target machine. Whereas, a metric measuring free memory would have
    only one instance value, representing the total amount of free memory on
    the target system.
    pmidnumvalvalfmtvlistrB   c                    sP    j dkr&t j}t fdd|D }t  j j j f}d| | S dS )Nr   c                    s   g | ]}d t  j|  qS z %s)rH   r   .0irU   r,   r-   
<listcomp>  s    z&pmValueSet.__str__.<locals>.<listcomp>z+pmValueSet@%#lx id=%#lx numval=%d valfmt=%d )r   rJ   r   rH   r   r   )r9   valsr   vsetr,   rU   r-   rA     s   

zpmValueSet.__str__c                 C   s   t | jd S r0   )r   _vlistrU   r,   r,   r-   
vlist_read  s   zpmValueSet.vlist_readN)r[   r\   r]   r   r   r   r   r   rA   r   propertyr   r,   r,   r,   r-   r     s    	
	r   c                 C      | j jS rX   )contentsr   r   r,   r,   r-   r         r   c                 C   r   rX   )r   r   r   r,   r,   r-   r     r   c                 C   r   rX   )r   r   r   r,   r,   r-   r     r   c                 C   r   rX   )r   r   r   r,   r,   r-   r     r   c                   @   sn   e Zd ZdZdefdefdeed fgZdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd Zdd ZdS )pmResultzStructure returned by pmFetch, with a value set for each metric queried

    The vset is defined with a "fake" array bounds of 1, which can give runtime
    array bounds complaints.  The getter methods are array bounds agnostic.
    	timestampnumpmidr   rB   c                 C   s   t |  d| _d S r0   )r   r2   r   rU   r,   r,   r-   r2     s   

zpmResult.__init__c                    s6   t  j}t fdd|D }dt  jf | S )Nc                    s    g | ]}d t  j| j qS r   )rH   r   r   r   rU   r,   r-   r     s     z$pmResult.__str__.<locals>.<listcomp>zpmResult@%#lx id#=%d )rJ   r   rH   r   )r9   r   r   r,   rU   r-   rA     s   
zpmResult.__str__c                 C   s   t | jtt}|| jjS )z# Return the pmid of vset[vset_idx] )r   r   r   pmValueSetPtrr   r   r9   vset_idxvsetptrr,   r,   r-   get_pmid  s   zpmResult.get_pmidc                 C       t | jttt}|| jjS )z% Return the valfmt of vset[vset_idx] )r   r   r   r   r   r   r   r,   r,   r-   
get_valfmt     zpmResult.get_valfmtc                 C   r  )z% Return the numval of vset[vset_idx] )r   r   r   r   r   r   r   r,   r,   r-   
get_numval  r  zpmResult.get_numvalc                 C   s   t | jttt}|| S )z Return the vset[vset_idx] )r   r   r   r   r   r,   r,   r-   get_vset  s   zpmResult.get_vsetc                 C   s    t | |jjtt}|| S )z/ Return the vlist[vlist_idx] of vset[vset_idx] )r   r  r   r   r   r   )r9   r   	vlist_idxlistptrr,   r,   r-   	get_vlist   s   zpmResult.get_vlistc                 C   s   |  ||jS )z8 Return the inst for vlist[vlist_idx] of vset[vset_idx] )r  r   )r9   r   r  r,   r,   r-   get_inst     zpmResult.get_instN)r[   r\   r]   r   rf   r   r   r   r   r2   rA   r   r  r  r  r  r	  r,   r,   r,   r-   r     s    r   c                   @   s:   e Zd ZdZdefdefdefdefdefgZdd Zd	S )
pmDescz"Structure describing a metric
    r   typeindomsemunitsc                 C   s   t | | j| jf}d| S )NzpmDesc@%#lx id=%#lx type=%d)r   r   r  )r9   fieldsr,   r,   r-   rA     s   zpmDesc.__str__N)	r[   r\   r]   r   r   r   r   r   rA   r,   r,   r,   r-   r    s    r  c                 C   r   rX   )r   r  r   r,   r,   r-   r     r   c                 C   r   rX   )r   r  r   r,   r,   r-   r     r   c                 C   r   rX   )r   r  r   r,   r,   r-   r     r   c                 C   r   rX   )r   r  r   r,   r,   r-   r     r   c                 C   s8   G dd dt }t| ttr| jjS | }| |_|jS )zInternal function to extract an indom from a pmdesc

       Allow functions requiring an indom to be passed a pmDesc* instead
    c                   @   s    e Zd ZdeefdefgZdS )zget_indom.<locals>.Valuer   r   N)r[   r\   r]   r   r  r   r   r,   r,   r,   r-   Value$  s    
r  )r   r5   r   r  r   r  r   r   )pmdescr  rT   r,   r,   r-   	get_indom  s   r  c                   @   sL   e Zd ZdZdefdefdefdefdeefgZdd Ze	dddZ
dS )pmMetricSpecz.Structure describing a metric's specification isarchsourcemetricninstr   c                    s8   t t fddt j}t  j j|f}d| S )Nc                    s   t  j|  S rX   )rH   r   r   rU   r,   r-   r   7  s    z&pmMetricSpec.__str__.<locals>.<lambda>z+pmMetricSpec@%#lx src=%s metric=%s insts=%s)r3   maprJ   r  r   r  r  )r9   instsr  r,   rU   r-   rA   6  s   zpmMetricSpec.__str__r   r   c                 C   sh   t |  }t }t|ts|d}t|ts|d}t|||t|t|}|dk r2t|||S Nr`   r   )	r   r   r5   rm   rb   rF   pmParseMetricSpecr   r/   )ro   stringr  r  rM   rr   rs   r,   r,   r-   
fromString;  s   






zpmMetricSpec.fromStringNr   r   )r[   r\   r]   r   r   r   r   r   rA   r   r  r,   r,   r,   r-   r  /  s    
r  c                   @   sN   e Zd ZdZdefdefdefdeej fdeej	 fgZ
dd Zd	d
 ZdS )
pmLogLabelz,Label record at the start of every log file magicpid_tstarthostnametzc                 C      t | j S )z6 Return the hostname from the structure as native str )rH   r$  rI   rU   r,   r,   r-   get_hostnameQ  r
  zpmLogLabel.get_hostnamec                 C   r&  )z6 Return the timezone from the structure as native str )rH   r%  rI   rU   r,   r,   r-   get_timezoneU  r
  zpmLogLabel.get_timezoneN)r[   r\   r]   r   r   rf   r   r<   PM_LOG_MAXHOSTLENPM_TZ_MAXLENr   r'  r(  r,   r,   r,   r-   r   I  s    r   c                   @   sD   e Zd ZdZdedfdedfdedfdedfdedfgZd	d
 ZdS )pmLabelz*Structure describing label's specificationname   namelenre   flagsrT   valuelenc                 C   s   | j d d | j d S )N:")r,  rT   rU   r,   r,   r-   rA   `  s   zpmLabel.__str__N)r[   r\   r]   r   r   r   rA   r,   r,   r,   r-   r+  Y  s    r+  c                 C   r   rX   )r   r,  r   r,   r,   r-   r   d  r   c                 C   r   rX   )r   r.  r   r,   r,   r-   r   e  r   c                 C   r   rX   )r   r/  r   r,   r,   r-   r   f  r   c                 C   r   rX   )r   rT   r   r,   r,   r-   r   g  r   c                 C   r   rX   )r   r0  r   r,   r,   r-   r   h  r   c                	   @   sV   e Zd ZdZdefdefdefdedfdedfd	ed
fdeefde	fgZ
dd ZdS )
pmLabelSetz. Structure describing label set specificationsr   nlabelsjsonjsonlenr-  padding   compoundrB   labelshashc                 C   s   | j d u rdS | j  S )Nz{})r5  rI   rU   r,   r,   r-   rA   t  s   

zpmLabelSet.__str__N)r[   r\   r]   r   r   r   r   r   r+  r   r   rA   r,   r,   r,   r-   r3  j  s    
r3  rB   c                   @   sh  e Zd ZdZdd Zdd Zdd Zdd	 Zeed
d
d
Z	eed
d
d
Z
eeed
d
ZdddZdd Zedd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Z d4d5 Z!d6d7 Z"d8d9 Z#d:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dTdU Z1dVdW Z2dXdY Z3dZd[ Z4d\d] Z5d^d_ Z6d`da Z7dbdc Z8ddde Z9dfdg Z:dhdi Z;djdk Z<dldm Z=dndo Z>dpdq Z?drds Z@dtdu ZAdvdw ZBdxdy ZCdzd{ ZDd|d} ZEd~d ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMd
S )	pmOptionsz Command line option parsing for short and long form arguments
        Passed into pmGetOptions, pmGetContextOptions, pmUsageMessage.
    c                 C   rW   rX   )_moderU   r,   r,   r-   _R_mode  rZ   zpmOptions._R_modec                 C   rW   rX   )_deltarU   r,   r,   r-   _R_delta  rZ   zpmOptions._R_deltac                 C   rW   rX   _need_resetrU   r,   r,   r-   _R_need_reset  rZ   zpmOptions._R_need_resetc                 C   s
   || _ d S rX   rA  )r9   rT   r,   r,   r-   _W_need_reset  r   zpmOptions._W_need_resetNr   c                 C   sd   t   |d urt | |d urt | |dkr t | nt t j d| _t j| _d| _	d S )Nr   rB   F)
r<   pmResetAllOptionspmSetShortOptionspmSetShortUsagepmSetOptionFlagsPM_OPTFLAG_BOUNDARIESr?  PM_MODE_INTERPr=  rB  )r9   short_optionsshort_usager/  r,   r,   r-   r2     s   


zpmOptions.__init__c                 C   s"   t d ur| jrt  d S d S d S rX   )rF   rB  r<   rE  rU   r,   r,   r-   __del__  s   zpmOptions.__del__c                   C      t  S )z> Cross-platform --daemonize (re-parent to init) option helper )r<   pmServerStartr,   r,   r,   r-   	daemonize  s   zpmOptions.daemonizec                 C   rN  rX   )r<   pmGetOptionFlagsrU   r,   r,   r-   rQ       zpmOptions.pmGetOptionFlagsc                 C   
   t |S rX   )r<   pmSetOptionContext)r9   contextr,   r,   r-   rT    r   zpmOptions.pmSetOptionContextc                 C   rS  rX   )r<   rH  )r9   r/  r,   r,   r-   rH    r   zpmOptions.pmSetOptionFlagsc                 C   rN  rX   )r<   pmGetOptionErrorsrU   r,   r,   r-   rV    rR  zpmOptions.pmGetOptionErrorsc                 C   s   t  d }t |S NrB   )r<   rV  pmSetOptionErrors)r9   errorsr,   r,   r-   rX    s   
zpmOptions.pmSetOptionErrorsc                 C   rS  rX   )r<   rG  )r9   rL  r,   r,   r-   rG    r   zpmOptions.pmSetShortUsagec                 C   rS  rX   )r<   rF  )r9   rK  r,   r,   r-   rF    r   zpmOptions.pmSetShortOptionsc                 C   rS  )z/ Set sample count (converts string to integer) )r<   pmSetOptionSamples)r9   countr,   r,   r-   rZ       
zpmOptions.pmSetOptionSamplesc                 C   rS  )z0 Set sampling interval (pmParseInterval string) )r<   pmSetOptionInterval)r9   rp   r,   r,   r-   r]    r\  zpmOptions.pmSetOptionIntervalc                 C   rN  )a!   After a pmGetOptions(3) call has been made this method
            returns a list of any remaining parameters which were
            not parsed as command line options, aka "operands".
            http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_254
        )r<   pmGetOperandsrU   r,   r,   r-   r^       zpmOptions.pmGetOperandsc                 C   rS  rX   r<   pmGetNonOptionsFromListr9   argvr,   r,   r-   ra    r   z!pmOptions.pmGetNonOptionsFromListc                 C   rS  rX   r`  rb  r,   r,   r-   pmNonOptionsFromList  r   zpmOptions.pmNonOptionsFromListc                 C   rS  )a   Handle individual command line options, outside of the PCP
            "standard" set (or overridden).

            For every non-standard or overridden option, this callback
            will be called with the short option character (as an int)
            or zero for long-option only, and the usual getopts global
            state (optind, opterr, optopt, optarg, and index - all int
            except optarg which is a str).
        )r<   pmSetOptionCallbackr9   funcr,   r,   r-   re    s   

zpmOptions.pmSetOptionCallbackc                 C   rS  )az   Allow a "standard" PCP option to be overridden.

            For every option parsed, this callback is called and it may
            return zero, meaning continue with processing the option in
            the standard way, or non-zero, meaning the caller wishes to
            override and interpret the option differently.
            Callback input: int, output: int
        )r<   pmSetOverrideCallbackrf  r,   r,   r-   rh  	  s   
	zpmOptions.pmSetOverrideCallbackc                 C   s   |du rd}t |||||S )a&   Add long option into the set of supported long options

            Pass in the option name (str), whether it takes an argument (int),
            its short option form (str), and two usage message hints (argname
            (str) and message (str) - see pmGetOptions(3) for details).
        Nr   )r<   pmSetLongOption)r9   long_opthas_arg	short_optargnamer?   r,   r,   r-   ri    s   zpmOptions.pmSetLongOptionc                 C   rS  )z> Add a new section heading into the long option usage message )r<   pmSetLongOptionHeader)r9   headingr,   r,   r-   rn    r\  zpmOptions.pmSetLongOptionHeaderc                 C   rS  )z> Add some descriptive text into the long option usage message )r<   pmSetLongOptionText)r9   textr,   r,   r-   rp  #  r\  zpmOptions.pmSetLongOptionTextc                 C   rN  )z4 Add support for -A/--align into PMAPI monitor tool )r<   pmSetLongOptionAlignrU   r,   r,   r-   rr  '     zpmOptions.pmSetLongOptionAlignc                 C   rN  )z6 Add support for -a/--archive into PMAPI monitor tool )r<   pmSetLongOptionArchiverU   r,   r,   r-   rt  +  rs  z pmOptions.pmSetLongOptionArchivec                 C   rN  )z4 Add support for -D/--debug into PMAPI monitor tool )r<   pmSetLongOptionDebugrU   r,   r,   r-   ru  /  rs  zpmOptions.pmSetLongOptionDebugc                 C      dS z Unimplemented Nr,   rU   r,   r,   r-   pmSetLongOptionGuiMode3     z pmOptions.pmSetLongOptionGuiModec                 C   rN  )z3 Add support for -h/--host into PMAPI monitor tool )r<   pmSetLongOptionHostrU   r,   r,   r-   rz  7  rs  zpmOptions.pmSetLongOptionHostc                 C   rN  )z8 Add support for -H/--hostsfile into PMAPI monitor tool )r<   pmSetLongOptionHostsFilerU   r,   r,   r-   r{  ;  rs  z"pmOptions.pmSetLongOptionHostsFilec                 C   rN  )z9 Add support for -K/--spec-local into PMAPI monitor tool )r<   pmSetLongOptionSpecLocalrU   r,   r,   r-   r|  ?  rs  z"pmOptions.pmSetLongOptionSpecLocalc                 C   rN  )z9 Add support for -L/--local-PMDA into PMAPI monitor tool )r<   pmSetLongOptionLocalPMDArU   r,   r,   r-   r}  C  rs  z"pmOptions.pmSetLongOptionLocalPMDAc                 C   rN  )z5 Add support for -O/--origin into PMAPI monitor tool )r<   pmSetLongOptionOriginrU   r,   r,   r-   r~  G  rs  zpmOptions.pmSetLongOptionOriginc                 C   rv  rw  r,   rU   r,   r,   r-   pmSetLongOptionGuiPortK  ry  z pmOptions.pmSetLongOptionGuiPortc                 C   rN  )z4 Add support for -S/--start into PMAPI monitor tool )r<   pmSetLongOptionStartrU   r,   r,   r-   r  O  rs  zpmOptions.pmSetLongOptionStartc                 C   rN  )z6 Add support for -s/--samples into PMAPI monitor tool )r<   pmSetLongOptionSamplesrU   r,   r,   r-   r  S  rs  z pmOptions.pmSetLongOptionSamplesc                 C   rN  )z5 Add support for -T/--finish into PMAPI monitor tool )r<   pmSetLongOptionFinishrU   r,   r,   r-   r  W  rs  zpmOptions.pmSetLongOptionFinishc                 C   rN  )z7 Add support for -t/--interval into PMAPI monitor tool )r<   pmSetLongOptionIntervalrU   r,   r,   r-   r  [  rs  z!pmOptions.pmSetLongOptionIntervalc                 C   rN  )z6 Add support for -V/--version into PMAPI monitor tool )r<   pmSetLongOptionVersionrU   r,   r,   r-   r  _  rs  z pmOptions.pmSetLongOptionVersionc                 C   rN  )z7 Add support for -Z/--timezone into PMAPI monitor tool )r<   pmSetLongOptionTimeZonerU   r,   r,   r-   r  c  rs  z!pmOptions.pmSetLongOptionTimeZonec                 C   rN  )z7 Add support for -z/--hostzone into PMAPI monitor tool )r<   pmSetLongOptionHostZonerU   r,   r,   r-   r  g  rs  z!pmOptions.pmSetLongOptionHostZonec                 C   rN  )z3 Add support for -?/--help into PMAPI monitor tool )r<   pmSetLongOptionHelprU   r,   r,   r-   r  k  rs  zpmOptions.pmSetLongOptionHelpc                 C   rN  )z8 Add support for --archive-list into PMAPI monitor tool )r<   pmSetLongOptionArchiveListrU   r,   r,   r-   r  o  rs  z$pmOptions.pmSetLongOptionArchiveListc                 C   rN  )z9 Add support for --archive-folio into PMAPI monitor tool )r<   pmSetLongOptionArchiveFoliorU   r,   r,   r-   r  s  rs  z%pmOptions.pmSetLongOptionArchiveFolioc                 C   rN  )z5 Add support for --container into PMAPI monitor tool )r<   pmSetLongOptionContainerrU   r,   r,   r-   r  w  rs  z"pmOptions.pmSetLongOptionContainerc                 C   rN  )z5 Add support for --host-list into PMAPI monitor tool )r<   pmSetLongOptionHostListrU   r,   r,   r-   r  {  rs  z!pmOptions.pmSetLongOptionHostListc                 C   rN  rX   )r<   pmGetOptionContextrU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionContextc                 C   rN  rX   )r<   pmGetOptionHostsrU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionHostsc                 C   rN  rX   )r<   pmGetOptionArchivesrU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionArchivesc                 C   s   t  }|d u r
d S t|S rX   )r<   pmGetOptionAlign_optargrf   rt   )r9   	alignmentr,   r,   r-   pmGetOptionAlignment  s   
zpmOptions.pmGetOptionAlignmentc                 C   "   t  }|d u r
d S t|t  S rX   )r<   pmGetOptionStart_secrf   pmGetOptionStart_usecr9   rj   r,   r,   r-   pmGetOptionStart     zpmOptions.pmGetOptionStartc                 C   rN  rX   )r<   r  rU   r,   r,   r-   pmGetOptionAlignOptarg  rR  z pmOptions.pmGetOptionAlignOptargc                 C   rN  rX   )r<   pmGetOptionFinish_optargrU   r,   r,   r-   pmGetOptionFinishOptarg  rR  z!pmOptions.pmGetOptionFinishOptargc                 C   r  rX   )r<   pmGetOptionFinish_secrf   pmGetOptionFinish_usecr  r,   r,   r-   pmGetOptionFinish  r  zpmOptions.pmGetOptionFinishc                 C   r  rX   )r<   pmGetOptionOrigin_secrf   pmGetOptionOrigin_usecr  r,   r,   r-   pmGetOptionOrigin  r  zpmOptions.pmGetOptionOriginc                 C   r  rX   )r<   pmGetOptionInterval_secrf   pmGetOptionInterval_usecr  r,   r,   r-   pmGetOptionInterval  r  zpmOptions.pmGetOptionIntervalc                 C   rN  rX   )r<   pmGetOptionSamplesrU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionSamplesc                 C      t  dkrdS dS Nr   FT)r<   pmGetOptionHostZonerU   r,   r,   r-   r       zpmOptions.pmGetOptionHostZonec                 C   rN  rX   )r<   pmGetOptionTimezonerU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionTimezonec                 C   rN  rX   )r<   pmGetOptionContainerrU   r,   r,   r-   r    rR  zpmOptions.pmGetOptionContainerc                 C   r  r  )r<   pmGetOptionLocalPMDArU   r,   r,   r-   r    r  zpmOptions.pmGetOptionLocalPMDAc                 C   rS  rX   )r<   pmSetOptionArchive)r9   archiver,   r,   r-   r    r   zpmOptions.pmSetOptionArchivec                 C   rS  rX   )r<   pmSetOptionArchiveList)r9   archivesr,   r,   r-   r    r   z pmOptions.pmSetOptionArchiveListc                 C   rS  rX   )r<   pmSetOptionArchiveFolio)r9   folior,   r,   r-   r    r   z!pmOptions.pmSetOptionArchiveFolioc                 C   rS  rX   )r<   pmSetOptionContainer)r9   	containerr,   r,   r-   r    r   zpmOptions.pmSetOptionContainerc                 C   rS  rX   )r<   pmSetOptionHost)r9   hostr,   r,   r-   r    r   zpmOptions.pmSetOptionHostc                 C   rS  rX   )r<   pmSetOptionHostList)r9   hostsr,   r,   r-   r    r   zpmOptions.pmSetOptionHostListc                 C   rS  rX   )r<   pmSetOptionSpecLocal)r9   specr,   r,   r-   r    r   zpmOptions.pmSetOptionSpecLocalc                 C   rN  rX   )r<   pmSetOptionLocalPMDArU   r,   r,   r-   r    rR  zpmOptions.pmSetOptionLocalPMDA)NNr   )Nr[   r\   r]   r   r>  r@  rC  rD  r   modedelta
need_resetr2   rM  staticmethodrP  rQ  rT  rH  rV  rX  rG  rF  rZ  r]  r^  ra  rd  re  rh  ri  rn  rp  rr  rt  ru  rx  rz  r{  r|  r}  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r,   r,   r,   r-   r<    s    

	r<  c                   @   s  e Zd ZdZdd Zdd Zdd ZeedddZeedddZ	eedddZ
ejd	fd
dZdd ZedddZedd Zdd Zdd Zdd Zdd ZdddZdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zed)d* Zd+d, Zd-d. Z ej!fd/d0Z"ej!fd1d2Z#dd3d4Z$d5d6 Z%d7d8 Z&d9d: Z'd;d< Z(d=d> Z)d?d@ Z*dAdB Z+edCdD Z,dEdF Z-dGdH Z.dIdJ Z/dKdL Z0dMdN Z1dOdP Z2edQdR Z3edSdT Z4edUdV Z5dWdX Z6dYdZ Z7d[d\ Z8ed]d^ Z9d_d` Z:dadb Z;dcdd Z<dedf Z=dgdh Z>didj Z?dkdl Z@ddndoZAdpdq ZBdrds ZCdtdu ZDdvdw ZEdxdy ZFdzd{ ZGd|d} ZHed~d ZIedddZJedddZKedd ZLedd ZMedd ZNedd ZOedd ZPedd ZQedd ZRedd ZSedd ZTedd ZUedd ZVedd ZWedd ZXedd ZYedd ZZedd Z[edd Z\edd Z]edd Z^edd Z_edd Z`edd Zaedd ZbedddZcedd Zdedd Zeedd Zfedd ZgedddZhedd ZieddĄ ZjeejkfddƄZleddȄ Zmddʄ ZndS )	pmContexta  Defines a metrics source context (e.g. host, archive, etc) to operate on

    pmContext(c_api.PM_CONTEXT_HOST,"local:")
    pmContext(c_api.PM_CONTEXT_ARCHIVE,"FILENAME")

    This object defines a PMAPI context, and its methods wrap calls to PMAPI
    library functions. Detailled information about those C library functions
    can be found in the following document.

    SGI Document: 007-3434-005
    Performance Co-Pilot Programmer's Guide
    Section 3.7 - PMAPI Procedural Interface, pp. 67

    Detailed information about the underlying data structures can be found
    in the same document.

    Section 3.4 - Performance Metric Descriptions, pp. 59
    Section 3.5 - Performance Metric Values, pp. 62
    c                 C   rW   rX   )_typerU   r,   r,   r-   _R_type  rZ   zpmContext._R_typec                 C   rW   rX   )_targetrU   r,   r,   r-   	_R_target  rZ   zpmContext._R_targetc                 C   rW   rX   )_ctxrU   r,   r,   r-   _R_ctx  rZ   zpmContext._R_ctxNlocal:c                 C   s\   || _ || _tj| _|rt|ts|d}n|}t	||| _| jdk r,t
| j|gd S r  )r  r  r<   PM_ERR_NOCONTEXTr  r5   rm   rb   rF   pmNewContextr/   )r9   r   targetr  r,   r,   r-   r2     s   
zpmContext.__init__c                 C   s,   t d ur| jtjkrt | j d S d S d S rX   )rF   r  r<   r  pmDestroyContextrU   r,   r,   r-   rM    s   zpmContext.__del__r   c           	      C   s   |du s|dkrd|_ t|rt| }|tjkr$| }|| }n-|tjkr2| }|| }n|tj	kr:d}n|
 durL| }|| }tj}ntj}d}| ||}t|j|j|jrbt|S )a   Helper interface, simple PCP monitor argument parsing.

            Take argv list, create a context using pmGetOptions(3)
            and standard options default values like local: etc
            based on the contents of the list.

            Caller should have already registered any options of
            interest using the option family of interfaces, i.e.
            pmSetShortOptions, pmSetLongOption*, pmSetOptionFlags,
            pmSetOptionCallback, and pmSetOptionOverrideCallback.

            When the MULTI/MIXED pmGetOptions flags are being used,
            the typed/index parameters can be used to setup several
            contexts based on the given command line parameters.
        Nr   Tr  )r  r<   pmGetOptionsFromListr_   r  PM_CONTEXT_ARCHIVEr  PM_CONTEXT_HOSTr  PM_CONTEXT_LOCALr  pmSetContextOptionsctxr  r  )	ro   optionsrc  r   rN   r  r  r  rU  r,   r,   r-   fromOptions  s.   






zpmContext.fromOptionsc                 C   s6  d}t  rt j}| t j |  d }n#t  r*t j}| t j |  d }nt  r9t j}| t j d}|spd|v rNt j}| | | t j n"|dkrat j}| 	| | t j nt j}| 
  | t j d}|t jkr|rtd|dD ]}| | q|  }| |t jB  t   ||fS )zF Helper to set connection options and to get context/source for pmfg. Nr   /@;)r<   r  r  rT  r  r  r  r  r  r  r  filtersplitr  rQ  rH  PM_OPTFLAG_DONEpmEndOptions)r  r  	speclocalrU  r  r/  r,   r,   r-   set_connect_optionsK  sB   

zpmContext.set_connect_optionsc                    s   t t  t| j}|dk rt|t|ts|d}t	|t
 }|dk r-t||dkrEtt fddt|}t  |S dS )zsPMAPI - Return names of children of the given PMNS node NAME
        tuple names = pmGetChildren("kernel")
        r   r`   c                       t  |   S rX   rH   rI   r   	offspringr,   r-   r         z)pmContext.pmGetChildren.<locals>.<lambda>N)r   r   rF   pmUseContextr  r/   r5   rm   rb   pmGetChildrenr   r3   r  rJ   LIBCfree)r9   r,  rs   childLr,   r  r-   r  z  s   



zpmContext.pmGetChildrenc                    s   t t t t  t| j}|dk rt|t|ts"|	d}t
|tt }|dk r5t||dkrattfddt|}tt fddt|}t t  ||fS dS )zPMAPI - Return names and status of children of the given metric NAME
        (tuple names,tuple status) = pmGetChildrenStatus("kernel")
        r   r`   c                    r  rX   r  r   r  r,   r-   r     r  z/pmContext.pmGetChildrenStatus.<locals>.<lambda>c                       t  |  S rX   r6   r   )	childstatr,   r-   r         NN)r   r   r   rF   r  r  r/   r5   rm   rb   pmGetChildrenStatusr   r3   r  rJ   r  r  )r9   r,  rs   r  statLr,   )r  r  r-   r    s&   





zpmContext.pmGetChildrenStatusc                 C   8   t | j}|dk rt|t  }|dk rt||S )zUPMAPI - Return the namespace location type
        loc = pmGetPMNSLocation()
        r   )rF   r  r  r/   pmGetPMNSLocationr9   rs   r,   r,   r-   r    s   zpmContext.pmGetPMNSLocationc                 C   sN   t | j}|dk rt|t|ts|d}t |}|dk r%t||S )zTPMAPI - Load a local namespace
        status = pmLoadNameSpace("filename")
        r   r`   )rF   r  r  r/   r5   rm   rb   pmLoadNameSpace)r9   filenamers   r,   r,   r-   r    s   


zpmContext.pmLoadNameSpacec           
      C   s,  t | j}|dk rt|t|ttfrd}nt|}t|  }t|tr0t|	d|d< n,t|tr<t||d< n t
|D ]\}}t|| trRt|||< q@t|	d||< q@t|  }tt| ttgt j_t |||}|dk r|t|||dkr||krdd t||D }	ttj|	|S )zPMAPI - Lookup pmIDs from a list of metric names nameA

        c_uint pmid [] = pmLookupName("MetricName")
        c_uint pmid [] = pmLookupName(("MetricName1", "MetricName2", ...))
        r   rB   r`   c                 S   s   g | ]\}}|t jkr|qS r,   )r<   
PM_ID_NULL)r   r,  r   r,   r,   r-   r     s    
z*pmContext.pmLookupName.<locals>.<listcomp>)rF   r  r  r/   r5   rH   rm   rK   r   rb   	enumerater   r   r   pmLookupNamer'   zipr<   PM_ERR_NAME)
r9   nameArelaxedrs   nnamesr   r,  pmidAbadLr,   r,   r-   r    s0   




zpmContext.pmLookupNamec                    sn   t | j}|dk rt|tt  t |t }|dk r#t|tt	 fddt
|}t  |S )zvPMAPI - Return list of all metric names having this identical PMID
        tuple names = pmNameAll(metric_id)
        r   c                    r  rX   r  r   nameA_pr,   r-   r     r  z%pmContext.pmNameAll.<locals>.<lambda>)rF   r  r  r/   r   r   	pmNameAllr   r3   r  rJ   r  r  )r9   r   rs   nameLr,   r  r-   r    s   

zpmContext.pmNameAllc                 C   s^   t  }t| j}|dk rt|t|t|}|dk r!t||j}t	| t
| S )zYPMAPI - Return a metric name from a PMID
        name = pmNameID(self.metric_id)
        r   )r   rF   r  r  r/   pmNameIDr   rT   r  r  rH   rI   )r9   r   r,  rs   rM   r,   r,   r-   r    s   
zpmContext.pmNameIDc                 C   s<   t | j}|dk rt|t||}|dk rt|dS )zPMAPI - Scan namespace, depth first, run CALLBACK at each node
        status = pmTraversePMNS("kernel", traverse_callback)
        r   N)rF   r  r  r/   r<   pmnsTraverse)r9   r,  callbackrs   r,   r,   r-   pmTraversePMNS  s   zpmContext.pmTraversePMNSc                 C   s8   t | j}|dk rt|t  }|dk rt|dS )zmPMAPI - Unloads a local PMNS, if one was previously loaded
        pm.pmUnLoadNameSpace("NameSpace")
        r   N)rF   r  r  r/   pmUnloadNameSpacer  r,   r,   r-   pmUnLoadNameSpace  s   zpmContext.pmUnLoadNameSpacec                 C   s   t |ts
|d}t |ts|d}t }t||t|}|dkr6t|j	 }t
| ttj|t| j}|dk rDt|dS )zPMAPI - Register a derived metric name and definition
        pm.pmRegisterDerived("MetricName", "MetricName Expression")
        r`   r   N)r5   rm   rb   r   rF   pmRegisterDerivedMetricr   rH   rT   rI   r  r  r/   r<   PM_ERR_CONVpmReconnectContextr  )r9   r,  exprrr   rM   rq  rs   r,   r,   r-   pmRegisterDerived  s   




zpmContext.pmRegisterDerivedc                 C   sN   t |ts
|d}t|}|dk rt|t| j}|dk r%t|dS )zuPMAPI - Register derived metric names and definitions from a file
        pm.pmLoadDerivedConfig("FileName")
        r`   r   N)r5   rm   rb   rF   pmLoadDerivedConfigr/   r	  r  )r9   fnamers   r,   r,   r-   r  )  s   


zpmContext.pmLoadDerivedConfigc                  C   s    t  } | durt|  S dS )zPMAPI - Return an error message if the pmRegisterDerived(3) metric
        definition cannot be parsed
        pm.pmRegisterDerived()
        N)rF   pmDerivedErrStrrH   rI   )rM   r,   r,   r-   r  8  s   zpmContext.pmDerivedErrStrc                 C   s`   t | j}|dk rt|ttt}t|t	t}t
|}t ||}|dk r.t||S )zvPMAPI - Lookup a metric description structure from a pmID

        pmDesc* pmdesc = pmLookupDesc(c_uint pmid)
        r   )rF   r  r  r/   r"   rD   r   r  r   r   r   pmLookupDesc)r9   pmid_prs   descbufdescr   r,   r,   r-   r  F  s   zpmContext.pmLookupDescc           	      C   s   t | j}|dk rt|t|trtd  }||d< ntt|  }t|D ]
\}}t|||< q(t	
t|tt }t|tt}t t|||}|dk rVt|ttt|  }tt|D ]
}t|| ||< qe|S )zPMAPI - Lookup metric description structures from pmIDs

        (pmDesc* pmdesc)[] = pmLookupDescs(c_uint pmid[N])
        (pmDesc* pmdesc)[] = pmLookupDescs(c_uint pmid)
        r   rB   )rF   r  r  r/   r5   integer_typesr   rK   r  r"   rD   r   r  r   r   pmLookupDescsrJ   r   )	r9   pmids_prs   pmidsr   r   descsbufdesclistdescsr,   r,   r-   r  X  s$   


zpmContext.pmLookupDescsc                 C   sd   t  }t| j}|dk rt|tt||t|}|dk r$t||j}t	
| t| S )z|PMAPI - Lookup the description of a metric's instance domain

        "instance" = pmLookupInDomText(pmDesc pmdesc)
        r   )r   rF   r  r  r/   pmLookupInDomTextr  r   rT   r  r  rH   rI   )r9   r  kindbufrs   rM   r,   r,   r-   r  w  s   
zpmContext.pmLookupInDomTextc                 C   sX   t  }t| j}|dk rt|t||t|}|dk r"t||j}t	| |S )zePMAPI - Lookup the description of a metric from its pmID
        "desc" = pmLookupText(pmid)
        r   )
r   rF   r  r  r/   pmLookupTextr   rT   r  r  )r9   r   r  r  rs   rq  r,   r,   r-   r    s   
zpmContext.pmLookupTextc                    s   |du r|du rt tjdtt  tt t| j}|dk r&t ||du r.t	|}t
|t t}|dk rAt ||dkrmttfddt|}tt fddt|}t  t ||fS d}d}||fS )zPMAPI - Lookup the list of instances from an instance domain PMDESCP or indom
        ([instance1, instance2...] [name1, name2...]) pmGetInDom(pmDesc pmdesc)
        Nzinvalid argumentsr   c                       t  |  ddS Nasciiignorer  r   r  r,   r-   r         z&pmContext.pmGetInDom.<locals>.<lambda>c                    r  rX   r  r   instA_pr,   r-   r     r  )r/   r<   PM_ERR_GENERICr   r   r   rF   r  r  r  
pmGetInDomr   r3   r  rJ   r  r  )r9   pmdescpr  rs   r   instLr,   r$  r  r-   r&    s*   



zpmContext.pmGetInDomc                 C   st   t | j}|dk rt|i }| j|d\}}|du s |du r"|S t|}t|D ]}||| || i q*|S )z1 helper to return dict of inst:name for an indom r   )r  N)rF   r  r  r/   r&  rK   rJ   update)r9   r  rs   retDr(  r   r  r   r,   r,   r-   pmGetInDomDict  s   zpmContext.pmGetInDomDictc                 C   T   t | j}|dk rt|t|ts|d}t t||}|dk r(t||S )zPMAPI - Lookup the instance id with the given NAME in the indom

        c_uint instid = pmLookupInDom(pmDesc pmdesc, "Instance")
        r   r`   )	rF   r  r  r/   r5   rm   rb   pmLookupInDomr  r9   r  r,  rs   r,   r,   r-   r.       

zpmContext.pmLookupInDomc                 C   sv   |t jkrdS t }t| j}|dk rt|tt||t	|}|dk r+t||j
}t| t|ddS )zPMAPI - Lookup the text name of an instance in an instance domain

        "string" = pmNameInDom(pmDesc pmdesc, c_uint instid)
        
PM_IN_NULLr   r   r!  )r<   r1  r   rF   r  r  r/   pmNameInDomr  r   rT   r  r  rH   rI   )r9   r  instvalname_prs   rM   r,   r,   r-   r2    s   

zpmContext.pmNameInDomc                 C   rv  )zPMAPI - NOOP - Establish a new PMAPI context (done in constructor)

        This is unimplemented. A new context is established when a pmContext
        object is created.
        Nr,   )r9   r   r,  r,   r,   r-   r    r   zpmContext.pmNewContextc                 C   rv  )zPMAPI - NOOP - Destroy a PMAPI context (done in destructor)

        This is unimplemented. The context is destroyed when the pmContext
        object is destroyed.
        Nr,   r9   handler,   r,   r-   r    r   zpmContext.pmDestroyContextc                 C   r  )zfPMAPI - Duplicate the current PMAPI Context

        This supports copying a pmContext object
        r   )rF   r  r  r/   pmDupContextr  r,   r,   r-   r7    s   zpmContext.pmDupContextc                 C   rv  )zPMAPI - NOOP - Set the PMAPI context to that identified by handle

        This is unimplemented. Context changes are handled by the individual
        methods in a pmContext class instance.
        Nr,   r5  r,   r,   r-   r    r   zpmContext.pmUseContextc                  C      t  } | dk rt| | S )zcPMAPI - Returns the handle of the current PMAPI context
        context = pmWhichContext()
        r   )rF   pmWhichContextr/   rs   r,   r,   r-   r9  	  s   zpmContext.pmWhichContextc                 C   s   t |trd}t|  }||d< n$|du s|sd}tt }nt|}t|  }t|D ]\}}|||< q,t| j}|dk rCt	|t
t|||}|dk rTt	||S )zPMAPI - add instances to list that will be collected from indom

        status = pmAddProfile(pmDesc pmdesc, c_uint instid)
        rB   r   N)r5   r6   r   r   rK   r  rF   r  r  r/   pmAddProfiler  r9   r  r(  numinstinstArN   rT   rs   r,   r,   r-   r;    s$   




zpmContext.pmAddProfilec                 C   s   |du s|sd}t t }nt|}t|  }t|D ]\}}|||< qt| j}|dk r2t|tt	|||}|dk rCt||S )zPMAPI - delete instances from list to be collected from indom

        status = pmDelProfile(pmDesc pmdesc, c_uint inst)
        status = pmDelProfile(pmDesc pmdesc, [c_uint inst])
        Nr   )
r   r   rK   r  rF   r  r  r/   pmDelProfiler  r<  r,   r,   r-   r?  ,  s   

zpmContext.pmDelProfilec                 C   sR   t | j}|dk rt|d}|durt|}t |||}|dk r't||S )z|PMAPI - set interpolation mode for reading archive files
        code = pmSetMode(c_api.PM_MODE_INTERP, timeval, 0)
        r   N)rF   r  r  r/   r   	pmSetMode)r9   r  timeValr  rs   whenr,   r,   r-   r@  B  s   zpmContext.pmSetModec                 C       t | j}|dk rt||S )zPMAPI - Reestablish the context connection

        Unlike the underlying PMAPI function, this method takes no parameter.
        This method simply attempts to reestablish the the context belonging
        to its pmContext instance object.
        r   )rF   r	  r  r/   r  r,   r,   r-   r	  Q  s   zpmContext.pmReconnectContextc                 C   s,   t j}t|}t| j||}t| S )zPMAPI - Lookup the hostname for the given context

        This method simply returns the hostname for the context belonging to
        its pmContext instance object.

        "hostname" = pmGetContextHostName()
        )	r<   r)  r"   rD   rF   pmGetContextHostName_rr  rH   rI   )r9   buflenbufferrM   r,   r,   r-   pmGetContextHostName]  s   
zpmContext.pmGetContextHostNamec                 C   r  )z5PMAPI - Query and set the current reporting timezone r   )rF   r  r  r/   pmNewContextZoner  r,   r,   r-   rH  m  s   zpmContext.pmNewContextZonec                 C   s2   t | ts
| d} t| }|dk rt||S )z:PMAPI - Create new zone handle and set reporting timezone r`   r   )r5   rm   rb   rF   	pmNewZoner/   )r%  rs   r,   r,   r-   rI  w  s   


zpmContext.pmNewZonec                 C   s   t | }|dk rt||S )z,PMAPI - Sets the current reporting timezone r   )rF   	pmUseZoner/   )	tz_handlers   r,   r,   r-   rJ    s   
zpmContext.pmUseZonec                  C   s6   t  } tt| }|dk rt|| j}t| S )z-PMAPI - Query the current reporting timezone r   )r   rF   pmWhichZoner   r/   rT   rH   rI   )tz_prs   r%  r,   r,   r-   rL    s   zpmContext.pmWhichZonec                 C   sF   t | j}|dk rt|t }tt|}t t|t| |S )z;PMAPI - convert the date and time for a reporting timezone r   )	rF   r  r  r/   r   r   r   pmLocaltimer   r9   secondsrs   rM   r   r,   r,   r-   rN    s   zpmContext.pmLocaltimec                 C   sP   t | j}|dk rt|td}tt|}t t	|| t
|j S )z:PMAPI - format the date and time for a reporting timezone r   r   )rF   r  r  r/   r"   rD   r   r   r   r   rH   rT   rI   rO  r,   r,   r-   r     s   
zpmContext.pmCtimec                 C   sP   t t }t| j}|dk rt|tt||t|}|dk r&t||S )zkPMAPI - Fetch pmResult from the target source

        pmResult* pmresult = pmFetch(c_uint pmid[])
        r   )	r   r   rF   r  r  r/   pmFetchrK   r   )r9   r  result_prs   r,   r,   r-   rQ    s   
zpmContext.pmFetchc                 C      t |  dS )zgPMAPI - Free a result previously allocated by pmFetch
        pmFreeResult(pmResult* pmresult)
        N)rF   pmFreeResultrR  r,   r,   r-   rT       zpmContext.pmFreeResultc                 C   sH   t |gtj_t| j}|dk rt|t|}|dk r"t||S )zoPMAPI - Set values on target source, inverse of pmFetch
        pmresult = pmStore(pmResult* pmresult)
        r   )r  rF   pmStorer'   r  r  r/   )r9   rM   rs   r,   r,   r-   rW    s   
zpmContext.pmStorec                 C   D   t  }t| j}|dk rt|tt|}|dk r t||S )z]PMAPI - Get the label record from the archive
        loglabel = pmGetArchiveLabel()
        r   )r   rF   r  r  r/   pmGetArchiveLabelr   )r9   loglabelrs   r,   r,   r-   rY    s   zpmContext.pmGetArchiveLabelc                 C   rX  )zAPMAPI - Get the last recorded timestamp from the archive
        r   )rf   rF   r  r  r/   pmGetArchiveEndr   )r9   rq   rs   r,   r,   r-   r[    s   zpmContext.pmGetArchiveEndc                    s   t t  t t t| j}|dk rt|t|}t|t	 t	}|dk r/t||dkr[t
tfddt|}t
t fddt|}t  t ||fS d}d}||fS )zPMAPI - Get the instance IDs and names for an instance domain

        ((instance1, instance2...) (name1, name2...)) pmGetInDom(pmDesc pmdesc)
        r   c                    r  r  r  r   r  r,   r-   r     r"  z-pmContext.pmGetInDomArchive.<locals>.<lambda>c                    r  rX   r  r   r#  r,   r-   r     r  N)r   r   r   rF   r  r  r/   r  pmGetInDomArchiver   r3   r  rJ   r  r  )r9   r'  rs   r  r   r(  r,   r)  r-   r\    s$   



zpmContext.pmGetInDomArchivec                 C   r-  )zPMAPI - Lookup the instance id with the given name in the indom

        c_uint instid = pmLookupInDomArchive(pmDesc pmdesc, "Instance")
        r   r`   )	rF   r  r  r/   r5   rm   rb   pmLookupInDomArchiver  r/  r,   r,   r-   r]    r0  zpmContext.pmLookupInDomArchivec                 C   sl   t  }t| j}|dk rt|t|}t||t|}|dk r&t||j}t	
| t|ddS )zPMAPI - Lookup the text name of an instance in an instance domain

        "string" = pmNameInDomArchive(pmDesc pmdesc, c_uint instid)
        r   r   r!  )r   rF   r  r  r/   r  pmNameInDomArchiver   rT   r  r  rH   rI   )r9   r  r   r4  rs   r  rM   r,   r,   r-   r^    s   
zpmContext.pmNameInDomArchivec                 C   sH   t t }t| j}|dk rt|tt|}|dk r"t||S )zbPMAPI - Fetch measurements from the target source

        pmResult* pmresult = pmFetch()
        r   )r   r   rF   r  r  r/   pmFetchArchiver   )r9   rR  rs   r,   r,   r-   r_  !  s   
zpmContext.pmFetchArchive   c                 C   s4   i }|dur|j dkr|jdurt|j }|S )zk return a dict of a pmLabelSet, i.e. {name: value, ...}
            flags arg is currently ignored
        Nr   )r6  r5  loadsrI   )r9   lsetr/  retr,   r,   r-   pmlabelset_to_dict/  s   zpmContext.pmlabelset_to_dictc                 C   s   i }t | j}|dk rt|| |}|  }|r#|tj|i | 	t 
|}|r5|tj|i |jtjkrK| |j}|rK|tj|i | |}|rZ|tj|i | |}|ri|tj|i |S )zPMAPI - Get all labels for a single metric, excluding instance
           level labels (use pmGetInstancesLabels for those).
           Return dict of {type: {name: value, ...}, ...}
        r   )rF   r  r  r/   r  pmGetContextLabelsr*  r<   PM_LABEL_CONTEXTpmGetDomainLabelspmID_domainPM_LABEL_DOMAINr  PM_INDOM_NULLpmGetInDomLabelsPM_LABEL_INDOMpmGetClusterLabelsPM_LABEL_CLUSTERpmGetItemLabelsPM_LABEL_ITEM)r9   r   rc  rs   r  rb  r,   r,   r-   pmLookupLabels:  s,   


zpmContext.pmLookupLabelsc                 C   s   i }t | j}|dk rt||tjkr|S tt }t |t	|}|dk r,t|t
|D ]}|| }|jdurI||jt|j i q0|dkrTt || |S )zPMAPI - Get instance level labels for all instances in indom
           return a dict {instid: {name: value, ...}, ...}
        r   N)rF   r  r  r/   r<   rj  r   r3  pmGetInstancesLabelsr   rJ   r5  r*  r   ra  rI   pmFreeLabelSets)r9   r  instlabelsDrs   rR  r   rb  r,   r,   r-   rr  \  s$   


zpmContext.pmGetInstancesLabelsc                 C   p   t t }t| j}|dk rt|t|t|}|dk r#t||dkr)i S | |d }| 	|d |S )zPMAPI - Get labels of a given metric identifier
           On success, this returns a dict of the labels in a single pmLabelSet
        r   rB   )
r   r3  rF   r  r  r/   ro  r   rd  rs  r9   r   rR  rs   rc  r,   r,   r-   ro  s     
zpmContext.pmGetItemLabelsc                 C   ru  )zPMAPI - Get labels of a given metric cluster
           On success, this returns a dict of the labels in a single pmLabelSet
        r   rB   )
r   r3  rF   r  r  r/   rm  r   rd  rs  rv  r,   r,   r-   rm    rw  zpmContext.pmGetClusterLabelsc                 C   s~   i }t t }t| j}|dk rt||tjkr|S t|t	|}|dk r,t||dkr=| 
|d }| |d |S )zPMAPI - Get labels of a given instance domain
           On success, this returns a dict of the labels in a single pmLabelSet
        r   rB   )r   r3  rF   r  r  r/   r<   rj  rk  r   rd  rs  )r9   r  indomLabelsDrR  rs   r,   r,   r-   rk    s   

zpmContext.pmGetInDomLabelsc                 C   ru  )zPMAPI - Get labels of a given performance domain
           On success, this returns a dict of the labels in a single pmLabelSet
        r   rB   )
r   r3  rF   r  r  r/   rg  r   rd  rs  )r9   domainrR  rs   rc  r,   r,   r-   rg    rw  zpmContext.pmGetDomainLabelsc                 C   sn   t t }t| j}|dk rt|tt|}|dk r"t||dkr(i S | |d }| 	|d |S )zPMAPI - Get labels of the current context
           On success, this returns a dict of the labels in a single pmLabelSet
        r   rB   )
r   r3  rF   r  r  r/   re  r   rd  rs  )r9   rR  rs   rc  r,   r,   r-   re    s   
zpmContext.pmGetContextLabelsc                 C   s   t | ts	| g}n| }ttj}tt|  }t|D ]\}}t|	d||< qt
|t||t|}|dk r>t||j}t|ddS )z3PMAPI - Merges string labels into a string
        r`   r   r   r!  )r5   r3   r"   rD   r<   PM_MAXLABELJSONLENr   rK   r  rb   rF   pmMergeLabelsr/   rT   rH   rI   )r:  labelsLrR  arg_arrr   labelrs   rM   r,   r,   r-   r{    s   
zpmContext.pmMergeLabelsc                 C   s  t tj}|du rdd }t|}| du rd|_n^t| ts#| g}ng }| D ]}t|tr4|| q'|dur=|	| q't
tt|  }t|D ]\}}	tt|	t
t||< qKtt|t}t|t||t|||}
|
dk rxt|
|j}t|ddS )zPMAPI - Merges list of pmLabelSets based on labelSets hierarchy into
           a string. Each list element may also be either a list or None.
        Nc                 S   rv  rW  r,   )r   yzr,   r,   r-   r     r   z,pmContext.pmMergeLabelSets.<locals>.<lambda>s   {}r   r   r!  )r"   rD   r<   rz  mergeLabelSetsCB_typerT   r5   r3   extendappendr   r3  rK   r  r   r   r   r   rF   pmMergeLabelSetsr/   rH   rI   )	labelSetsr  argrR  cb_func
labelSetsLr   r}  r   labelsetrs   rM   r,   r,   r-   r    s4   



zpmContext.pmMergeLabelSetsrB   c                 C   s8   t |D ]}tt| | tt}|rt|d qdS )z{PMAPI - Free the pmLabelSets memory. The labelsets argument is
           an array of nsets pmLabelSet structures.
        rB   N)rJ   r   r   r   r3  rF   rs  )r  nsetsr   r  r,   r,   r-   rs  	  s   zpmContext.pmFreeLabelSetsc                 C   s6   t | ts
| d} t| }|du r|S t| S )z@PMAPI - Return single value from environment or pcp config file r`   N)r5   rm   rb   rF   pmGetOptionalConfigrH   rI   )variablerM   r,   r,   r-   pmGetConfig	  s   


zpmContext.pmGetConfigc                 C   s(   t tj}t| |tj}t| S )z4PMAPI - Convert an error code to a readable string  )r"   rD   r<   rE   rF   rG   rH   rI   )r7   errstrrM   r,   r,   r-   pmErrStr	  s   zpmContext.pmErrStrc                 C   s0   t  }t| ||t||}|dk rt||S )aO  PMAPI - Extract a value from a pmValue struct and convert its type

        pmAtomValue = pmExtractValue(results.contents.get_valfmt(i),
                                     results.contents.get_vlist(i, 0),
                                     descs[i].contents.type,
                                     c_api.PM_TYPE_FLOAT)
        r   )r   rF   pmExtractValuer   r/   )r   r   intypeouttypeoutAtomrs   r,   r,   r-   r  	  s   	
zpmContext.pmExtractValuec                 C   sf   t |trt }d|_||_n|}t }t| t|t|| j	j
t|t|}|dk r1t||S )zPMAPI - Convert a value to a different scale

        pmAtomValue = pmConvScale(c_api.PM_TYPE_FLOAT, pmAtomValue,
                                            pmDesc*, 3, c_api.PM_SPACE_MBYTE)
        rB   r   )r5   r6   r   r   r   r   rF   pmConvScaler   r   r  r/   )inTypeinAtomr  
metric_idxoutUnitspmunitsr  rs   r,   r,   r-   r  /	  s   
zpmContext.pmConvScalec                 C   r   )z2PMAPI - Convert units struct to a readable string r   r   )r  r   rM   r,   r,   r-   
pmUnitsStrD	     
zpmContext.pmUnitsStrc                 C   r   )z3PMAPI - Convert double value to fixed-width string re   )r"   rD   rF   pmNumberStr_rrH   rI   )rT   numstrrM   r,   r,   r-   pmNumberStrK	  r  zpmContext.pmNumberStrc                 C   s   t | ||}|S )z/PMAPI - build a pmID from domain, cluster, item)rF   
pmID_build)r   r   r   rM   r,   r,   r-   r  R	  s   zpmContext.pmID_buildc                 C      t | }|S )z&PMAPI - return domain number from pmID)rF   rh  r   rM   r,   r,   r-   rh  X	     
zpmContext.pmID_domainc                 C   r  )z'PMAPI - return cluster number from pmID)rF   pmID_clusterr  r,   r,   r-   r  ^	  r  zpmContext.pmID_clusterc                 C   r  )z$PMAPI - return item number from pmID)rF   	pmID_itemr  r,   r,   r-   r  d	  r  zpmContext.pmID_itemc                 C   r   )z,PMAPI - Convert a pmID to a readable string r   )r"   rD   rF   	pmIDStr_rrH   rI   )r   pmidstrrM   r,   r,   r-   pmIDStrj	  r  zpmContext.pmIDStrc                 C   s   t | |}|S )z-PMAPI - build an indom from domain and serial)rF   pmInDom_build)r   srM   r,   r,   r-   r  q	  s   zpmContext.pmInDom_buildc                 C   r  )z'PMAPI - return domain number from indom)rF   pmInDom_domainr  rM   r,   r,   r-   r  w	  r  zpmContext.pmInDom_domainc                 C   r  )z'PMAPI - return serial number from indom)rF   pmInDom_serialr  r,   r,   r-   r  }	  r  zpmContext.pmInDom_serialc                 C   s(   t d}tt| |d}t| S )zpPMAPI - Convert an instance domain ID  to a readable string
        "indom" = pmGetInDom(pmDesc pmdesc)
        r   )r"   rD   rF   pmInDomStr_rr  rH   rI   )r'  indomstrrM   r,   r,   r-   
pmInDomStr	  s   
zpmContext.pmInDomStrc                 C   r   )zwPMAPI - Convert a performance metric type to a readable string
        "type" = pmTypeStr(c_api.PM_TYPE_FLOAT)
        r   )r"   rD   rF   pmTypeStr_rrH   rI   )r   typestrrM   r,   r,   r-   	pmTypeStr	     
zpmContext.pmTypeStrc                 C   s*   t d}tt| ||d}t| S )zoPMAPI - Convert a value atom to a readable string
        "value" = pmAtomStr(atom, c_api.PM_TYPE_U32)
        `   )r"   rD   rF   pmAtomStr_rr   rH   rI   )atomr   atomstrrM   r,   r,   r-   	pmAtomStr	  s   
zpmContext.pmAtomStrc                 C   r   )z}PMAPI - Convert a performance metric semantic to a readable string
        "string" = pmSemStr(c_api.PM_SEM_COUNTER)
        r   )r"   rD   rF   
pmSemStr_rrH   rI   )r  semstrrM   r,   r,   r-   pmSemStr	  r  zpmContext.pmSemStrc                 C   sF   t t| t|jj| jjt|jjt|jj| jj	| | dS )zzPMAPI - Print the value of a metric
        pmPrintValue(file, value, pmdesc, vset_index, vlist_index, min_width)
        N)
rF   pmPrintValuer.   r   r   r   r   r  r   r   )r+   rM   ptyper   r  	min_widthr,   r,   r-   r  	  s   

zpmContext.pmPrintValuec                  C   r8  )z7PMAPI - flush the internal buffer shared with pmprintf r   )rF   pmflushr/   r:  r,   r,   r-   r  	  s   zpmContext.pmflushc                 G   s&   t j| g|R  }|dk rt|dS )z=PMAPI - append message to internal buffer for later printing r   N)rF   ra   r/   )fmtr4   rs   r,   r,   r-   ra   	  s   zpmContext.pmprintfc                 C   rS  )z@PMAPI - sort all metric instances in result returned by pmFetch N)rF   pmSortInstancesrU  r,   r,   r-   r  	  s   zpmContext.pmSortInstancesc                 C   s   t | dfS )zPMAPI - parse a textual time interval into a timeval struct
        (timeval_ctype, '') = pmParseInterval("time string")
        r   )rf   rt   )rp   r,   r,   r-   rn   	  rV  zpmContext.pmParseIntervalr   c                 C   s   t | ||dfS )zPMAPI - parse a textual metric specification into a struct
        (result, '') = pmParseMetricSpec("hinv.ncpu", 0, "localhost")
        r   )r  r  )r  r  r  r,   r,   r-   r  	  s   zpmContext.pmParseMetricSpecc                 C   s   t | ttfsttjt| t | ts| d} t }t	 }t
 }t| t|t|t|}|dk rEt|j }t| t||||jfS r  )r5   rm   	text_typer/   r<   r  rH   rb   r   r   r	   rF   pmParseUnitsStrr   rT   rI   r  r  )r  rM   rr   
multiplierrs   rq  r,   r,   r-   r  	  s   




zpmContext.pmParseUnitsStrc                 C   s   |   S )z Delay for a specified amount of time (timeval).
            Useful for implementing tools that do metric sampling.
            Single arg is timeval in tuple returned from pmParseInterval().
        )r   )rq   r,   r,   r-   pmtimevalSleep	  r_  zpmContext.pmtimevalSleepc                   C   rO   rP   rR   r,   r,   r,   r-   rQ   	  s   zpmContext.pmPrognamec                 C   s   t tdj| @ rdS dS )NpmDebugTF)r   rS   rF   rT   )r/  r,   r,   r-   r  	  s   zpmContext.pmDebugc                 C   s   |dkr|rdnd}n| rt |  j}nt  j}|r t jnt j}t j| }|rPt|d }t|d d }|dkr@|d7 }|t|7 }|rP|dt| 7 }|S )z; Get current timezone offset string using POSIX convention r   rB         @i  <   +r1  )	r   	localtimer  r   altzonetimezonetznamer6   rH   )r  set_dstdstoffsetr  	offset_hr
offset_minr,   r,   r-   get_current_tz	  s    

zpmContext.get_current_tzc                    sb    rd fdddD vrdS d v r  dd n  dd }d v r'dnd}d	| t| S )
zC Convert POSIX timezone offset string to human readable UTC offset Tc                    s   g | ]}| v qS r,   r,   )r   r   r  r,   r-   r   
  r"  z4pmContext.posix_tz_to_utc_offset.<locals>.<listcomp>)r  -zUTC+0r  rB   r  UTC)r  rH   )r  r  signr,   r  r-   posix_tz_to_utc_offset
  s
   $z pmContext.posix_tz_to_utc_offsetc                 C   s|   |   r|   tjd< t  t|    dS |  r)t tjd< t  dS t	| }|tjd< t  t| dS )z  Set timezone for a Python tool TZN)
r  r(   environr   tzsetr  rI  r  rL  r  )r  r  r,   r,   r-   set_timezone
  s   

zpmContext.set_timezonec                 C   s   | t j d }|tjkr |j|j|jd d  d  d }|S |tjkr8|j|j|jd d  d  d }|S |tjkrP|j|j|jd d  d  d }|S |tj	krh|j|j|jd d  d  d }|S t
d)z6 Convert datetime value to seconds of given precision r   g      8@r  g    .Ag     @@g      ?zUnsupported precision requested)datetimefromtimestampr<   PM_TIME_SECmicrosecondsrP  daysPM_TIME_MSECPM_TIME_USECPM_TIME_NSEC
ValueError)rT   	precisiontdttstr,   r,   r-   datetime_to_secs'
  s   
"	
"
"
"zpmContext.datetime_to_secsc                 C   sp   |r| r
t j}d}n(t j}d}|j|kr |j}|t t jO }n|jd |jd  }|t t jO }|t|fS )z! Get mode and step for pmSetMode r   i    )	r<   PM_MODE_FORWrJ  rg   
PM_XTB_SETr  rh   r  r6   )r  interpolrp   r  stepsecs_in_24_daysr,   r,   r-   get_mode_step7
  s   
zpmContext.get_mode_stepc                 C   s^   t | j}|dk rt|| | | jtjkr-t	|||\}}| 
|| | dS dS )z Common execution preparation r   N)rF   r  r  r/   r  r  r<   r  r  r  r@  r  )r9   r  r  r  rp   rs   r  r  r,   r,   r-   prepare_executeH
  s   
zpmContext.prepare_executer   )r   r  )r`  )rB   r  )Nr  )or[   r\   r]   r   r  r  r  r   r  r  r  r<   r  r2   rM  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  PM_TEXT_ONELINEr  r  r&  r,  r.  r2  r  r  r7  r  r9  r;  r?  r@  r	  rG  rH  rI  rJ  rL  rN  r   rQ  rT  rW  rY  r[  r\  r]  r^  r_  rd  rq  rr  ro  rm  rk  rg  re  r{  r  rs  r  r  r  r  r  r  r  rh  r  r  r  r  r  r  r  r  r  r  r  r  ra   r  rn   r  r  r  rQ   r  r  r  r  r  r  r  r  r,   r,   r,   r-   r    s$   /
.
#


	

	

	


"
#	
	





























r  c                   @   s   e Zd ZdZG dd deZG dd deZG dd deZG dd	 d	eZG d
d de	Z
ejdfddZdd Zdd Zd!ddZd"ddZdd Zd#ddZdd Zdd  ZdS )$
fetchgroupa  Defines a PMAPI fetchgroup.

    This class wraps the pmFetchGroup set of C PMAPI functions (q.v.)
    in an object-oriented manner.

    Each instance of this class represents one fetchgroup, in which
    interest in several metrics (individual or indoms) is registered.
    Each registration results in an function-like object that may be
    called to decode that metric's value(s).  Errors are signalled
    with exceptions rather than result integers.  Strings are all
    UTF-8 encoded.
    c                   @       e Zd ZdZdd Zdd ZdS )zfetchgroup.fetchgroup_itemz
        An internal class to receive value/status for a single item.
        It may be called as if it were a function object to decode
        the embedded pmAtomValue, which was set at the most recent
        .fetch() call.
        c                 C   s   t tj| _|| _t | _dS z8Allocate a single instance to receive a fetchgroup item.N)r   r<   PM_ERR_VALUEstspmtyper   rT   )r9   r  r,   r,   r-   r2   
  s   z#fetchgroup.fetchgroup_item.__init__c                 C   s&   | j jdk rt| j j| j| jS )>Retrieve a converted value of a fetchgroup item, if available.r   )r  rT   r/   r   r  rU   r,   r,   r-   __call__
  s   z#fetchgroup.fetchgroup_item.__call__Nr[   r\   r]   r   r2   r  r,   r,   r,   r-   fetchgroup_item
  s    r  c                   @   r  )zfetchgroup.fetchgroup_timestampz
        An internal class to receive value for a single timestamp.
        It may be called as if it were a function object to decode
        the timestamp, which was set at the most recent
        .fetch() call, into a datetime object.
        c                 C   s   t  | _|| _dS )z=Allocate a single instance to receive a fetchgroup timestamp.N)rf   rT   r  )r9   r  r,   r,   r-   r2   
  s   
z(fetchgroup.fetchgroup_timestamp.__init__c              
   C   sL   | j | jj}t| jj}t|jd |jd |j	|j
|j|j|d}|S )z
            Retrieve a converted value of a timestamp, if available.  Use
            pmLocaltime() to convert to a datetime object.
            r   rB   N)r  rN  rT   rg   r6   rh   r  r   r   r   r   r   r   )r9   tsusdtr,   r,   r-   r  
  s   z(fetchgroup.fetchgroup_timestamp.__call__Nr  r,   r,   r,   r-   fetchgroup_timestamp
  s    r  c                   @   r  )zfetchgroup.fetchgroup_indomaq  
        An internal class to receive value/status for an indom of
        items.  It may be called as if it were a function object to
        create an list of tuples containing instance-code/-name/value
        information.  Each value is a function object that decodes
        the embedded pmAtomValue, which was set at the most recent
        fetch() call.
        c                 C   sZ   t | }t| }t| }t| }t  | _| | _|| _| | _| | _| | _	t | _
dS r  )r   r   r   r   r  stssr  valuesicodesinamesnum)r9   r  r  stss_tvalues_ticodes_tinames_tr,   r,   r-   r2   
  s   z$fetchgroup.fetchgroup_indom.__init__c                    sx   g }j jdk rtj jtjjD ]%}dd  |j| j| r-j| dnd fdd|f q|S )r  r   c                 S   .   | j | dk rt| j | | j| | jS r0   r  r/   r  r   r  r9   r   r,   r,   r-   
decode_one
     z8fetchgroup.fetchgroup_indom.__call__.<locals>.decode_oner`   Nc                        fddS )Nc                      
    S rX   r,   r,   r  r   r9   r,   r-   r   
     
 zHfetchgroup.fetchgroup_indom.__call__.<locals>.<lambda>.<locals>.<lambda>r,   r   r  r9   r  r-   r   
  r  z6fetchgroup.fetchgroup_indom.__call__.<locals>.<lambda>)	r  rT   r/   rJ   r  r  r  r  rI   )r9   vvr   r,   r  r-   r  
  s   z$fetchgroup.fetchgroup_indom.__call__Nr  r,   r,   r,   r-   fetchgroup_indom
  s    	r  c                   @   r  )zfetchgroup.fetchgroup_eventak  
        An internal class to receive value/status for an
        event record field.  It may be called as if it were a function
        object to create an list of tuples containing timestamp/value
        information.  Each value is a function object that decodes
        the embedded pmAtomValue, which was set at the most recent
        fetch() call.
        c                 C   sP   t | }t| }t| }t  | _| | _|| _| | _| | _t | _	|| _
dS r  )r   r   r   r  r  r  timesr  r   r  r  )r9   r  r  r  r  r  
timespec_tr,   r,   r-   r2   
  s   
z$fetchgroup.fetchgroup_event.__init__c                    s   g }j jdk rtj jtjjD ]>}dd  jj| j}t	j| j
d }t|jd |jd |j|j|j|j|d}|| fdd	|f q|S )
r  r   c                 S   r  r0   r  r  r,   r,   r-   r  
  r  z8fetchgroup.fetchgroup_event.__call__.<locals>.decode_oner  r   rB   Nc                    r  )Nc                      r  rX   r,   r,   r  r,   r-   r     r  zHfetchgroup.fetchgroup_event.__call__.<locals>.<lambda>.<locals>.<lambda>r,   r  r  r  r-   r     r  z6fetchgroup.fetchgroup_event.__call__.<locals>.<lambda>)r  rT   r/   rJ   r  r  rN  r  rg   r6   r   r  r   r   r   r   r   r   r  )r9   r  r   r  r  r   r,   r  r-   r  
  s   z$fetchgroup.fetchgroup_event.__call__Nr  r,   r,   r,   r-   fetchgroup_event
  s    	r  c                   @   r  )zfetchgroup.pmContext_borrowedz
        An internal class for accessing the private PMAPI context
        belonging to a fetchgroup.  It works just like a pmContext,
        except it overrides the constructor/destructor to reflect
        the "borrowed" state of the context.
        c                 C   s   || _ || _|| _dS )z/Override pmContext ctor to eschew pmNewContext.N)r  r  r  )r9   r  r   r  r,   r,   r-   r2     s   
z&fetchgroup.pmContext_borrowed.__init__c                 C   s(   t dur| jt jkrt j| _dS dS dS )z3Override pmContext ctor to eschew pmDestroyContext.N)r<   r  r  rU   r,   r,   r-   rM    s   z%fetchgroup.pmContext_borrowed.__del__N)r[   r\   r]   r   r2   rM  r,   r,   r,   r-   pmContext_borrowed  s    r  r  c                 C   sj   t  | _g | _|tjkr|du rd}tt| j||d}|dk r't	|t
t| j||| _dS )z%Create a fetchgroup from a pmContext.Nr   r`   r   )r   pmfgitemsr<   r  rF   pmCreateFetchGroupr   rb   r/   r  r  pmGetFetchGroupContextr  )r9   r   r  r  r,   r,   r-   r2      s   
zfetchgroup.__init__c                 C   s@   t dur| jjdurt | j}|dk rt|| jdd= dS )z?Destroy the fetchgroup.  Drop references to fetchgroup_* items.Nr   )rF   r  rT   pmDestroyFetchGroupr/   r  r9   r  r,   r,   r-   rM  ,  s
   zfetchgroup.__del__c                 C   rW   )z
        Return the private pmContext used by the fetchgroup.
        WARNING: mutation of this context by other PMAPI functions
        may disrupt fetchgroup functionality.
        )r  rU   r,   r,   r-   get_context4  s   zfetchgroup.get_contextNc           	   
   C   s   |du r
t tj |du r| j|}| j|}|d j}t|}t	
| jt|r0|dndt|r:|dndt|rD|dndt|jt|t|j}|dk r[t || j| |S )zExtend the fetchgroup with a single metric.  Infer type if
        necessary.  Convert scale/rate if appropriate/requested.
        Requires a specified instance if metric has an instance
        domain.
        Nr   r`   )r/   rY   EINVALr  r  r  r  r  r  rF   pmExtendFetchGroup_itemr  r   rb   r   rT   r   r  r  r  )	r9   r  mtypescaleinstancer  r  vr  r,   r,   r-   extend_item<  s$   

zfetchgroup.extend_itemd   c           	      C   s
  |du s|dk rt tj |du r#| j|}| j|}|d j}t||}t	
| jt|r5|dndt|r?|dndtt|jtttt|jtttt|jttt|tt|jttt|t|jt|j}|dk r}t || j| |S )zExtend the fetchgroup with up to @maxnum instances of a metric.
        (Metrics without instances are also accepted.)  Infer type if
        necessary.  Convert scale/rate if appropriate/requested.
        Nr   r`   )r/   rY   r#  r  r  r  r  r  r  rF   pmExtendFetchGroup_indomr  r   rb   r   r   r  r   r   r  r  r   r  r   r  r  r  r  )	r9   r  r%  r&  maxnumr  r  r  r  r,   r,   r-   extend_indomW  s*   
	zfetchgroup.extend_indomc                 C   s@   t | j}t| jt|j}|dk rt|| j	
| |S )z.Extend the fetchgroup with a timestamp query. r   )r  r  r  rF   pmExtendFetchGroup_timestampr  r   rT   r/   r  r  )r9   r(  r  r,   r,   r-   extend_timestamps  s   zfetchgroup.extend_timestampc                 C   s$  |du s|dk rt tj |du r#| j|}| j|}|d j}t||| j}	t	
| jt|r7|dndt|rA|dndt|rK|dndt|rU|dndtt|	jtttt|	jttt|tt|	jttt|t|	jt|	j}
|
dk rt |
| j|	 |	S )zExtend the fetchgroup with up to @maxnum instances of the given
        field of the given event metric's records.  Infer type if necessary.
        Convert scale if appropriate/requested.
        Nr   r`   )r/   rY   r#  r  r  r  r  r  r  rF   pmExtendFetchGroup_eventr  r   rb   r   r   r  r   r   r  r   r   r  r   r  r  r  r  )r9   r  fieldftyper&  r'  r,  r  r  r  r  r,   r,   r-   extend_event}  s,   

zfetchgroup.extend_eventc                 C   rC  )z?Fetch all the metrics in this fetchgroup and update all values.r   )rF   pmFetchGroupr  r/   r!  r,   r,   r-   fetch  s   zfetchgroup.fetchc                 C   s2   t | j}| jdd= |dk rt|g | _dS )z>Clear all the metrics in this fetchgroup ready to start again.Nr   )rF   pmClearFetchGroupr  r  r/   r!  r,   r,   r-   clear  s
   
zfetchgroup.clear)NNNN)NNNr*  )NNNNNr*  )r[   r\   r]   r   objectr  r  r  r  r  r  r<   r  r2   rM  r"  r)  r-  r/  r3  r5  r7  r,   r,   r,   r-   r  z
  s     )-



r  )r   r(   r    r   rY   r  r5  cpmapir<   r"   r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   ctypes.utilr   rF   platform	libc_namer  r!   r6   r  r   rH   r  unicoder.   r   r/   r_   PM_SIZEOF_SUSECONDS_Tr   r  PM_SIZEOF_TIME_Tr   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   pmIDpmInDomr  	pmDescPtrr  r  r  r  r  r  r   r+  
pmLabelPtrr,  r.  r/  rT   r0  r3  r  r%   r'   r  r  r  r  r  r  traverseCB_typer  r  r  r  r  r  r  r  r&  r.  r2  r  r  r7  r  r9  r;  r?  r@  r	  rD  rH  rI  rJ  rL  rN  r   rQ  rT  rW  rY  r[  r\  r]  r^  r_  r  rG   r  r  r   r  r  rh  r  r  r  r  r  r  r  r  r  r  r  rn   r  r  ra   r  rq  rr  ro  rm  rk  rg  re  r{  r  r  rs  r8  r<  r  r  r  r6  r   r$  r+  r0  r.  r4  r  r,   r,   r,   r-   <module>   sN   \  
!



+)&*0

















  F           


	

