o
     bP                     @   s8  d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	m
Z
mZ ddl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 eedZeej_eeeegej_eej_eeeeegej_eej_eeeeeegej_eej_eeeeeegej_eej_eeeeeeeeeegej_eej _eegej _eej!_eegej!_eej"_eeeegej"_eej#_eeegej#_eej$_eeeegej$_eej%_g ej%_d	d
 Z"dd Z#dd Z$d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+G dd de+Z,dS )a  Wrapper module for libpcp_pmda - Performace Co-Pilot Domain Agent API
#
# Copyright (C) 2013-2015,2017-2021 Red Hat.
#
# 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.
#
# See pmdasimple.py for an example use of this module.
    N)	pmContext)pmInDompmDescpmUnitspmErr
pmLabelSet)find_library)CDLLc_intc_longc_char_pc_void_p)	addressofbyrefPOINTER	Structurepcp_pmdac                 C   .   t t }tt|| }|dk rt||S Nr   )r   r   LIBPCP_PMDApmdaAddLabelsr   r   labelresult_pstatus r   */usr/lib/python3/dist-packages/pcp/pmda.pyr   F   
   
r   c                 C   s    t | |}|dk rt||S r   )r   pmdaAddLabelFlagsr   )labelsflagsr   r   r   r   r   M   s   r   c                 C   r   r   )r   r   r   pmdaAddNotesr   r   r   r   r   r   r!   S   r   r!   c                  C   s   t  } | dk rt| | S r   )r   pmdaGetContextr   )r   r   r   r   r"   Z   s   r"   c                   @   0   e Zd ZdZdefdefgZdd Zdd ZdS )	
pmdaMetricz5 Structure describing a metric definition for a PMDA m_userm_descc                 C   s<   t |  d | _|| j_|| j_|| j_|| j_|| j_d S N)	r   __init__r%   r&   pmidtypeindomsemunits)selfr)   typeofr+   r,   r-   r   r   r   r(   i   s   
zpmdaMetric.__init__c                 C   s   dt | | jj| jjf S )Nz!pmdaMetric@%#lx pmid=%#lx type=%d)r   r&   r)   r*   r.   r   r   r   __str__r      zpmdaMetric.__str__N)	__name__
__module____qualname____doc__r   r   _fields_r(   r1   r   r   r   r   r$   d   s    	r$   c                   @   r#   )	
pmdaInstidz6 Structure describing an instance (index/name) a PMDA i_insti_namec                 C   s    t |  || _|d| _d S )Nutf-8)r   r(   r9   encoder:   )r.   instidnamer   r   r   r(   z   s   
zpmdaInstid.__init__c                 C      dt | | j| jf S )Nz pmdaInstid@%#lx index=%d name=%s)r   r9   r:   r0   r   r   r   r1         zpmdaInstid.__str__N)	r3   r4   r5   r6   r
   r   r7   r(   r1   r   r   r   r   r8   u   s    r8   c                   @   s   e Zd ZdZdefdefdee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d Zdd Zdd Zdd Zdd ZdS ) 	pmdaIndomz7 Structure describing an instance domain within a PMDA it_indom
it_numinstit_setc                 C   s8   t |  d| _d | _|| _| || | || d S r   )r   r(   rC   rD   rB   
load_indomset_instancesr.   r+   instsr   r   r   r(      s   
zpmdaIndom.__init__c                 c   s    | j dkr*t| jtj 	 t| jtj}|dk rd S | |}|r)||fV  qt| j D ]}| j	| j
}| |}|rC||fV  q/d S r   )rC   r   pmdaCacheOprB   cpmdaPMDA_CACHE_WALK_REWINDPMDA_CACHE_WALK_NEXTinst_name_lookuprangerD   r9   )r.   instr>   ir   r   r   __iter__   s,   


	

zpmdaIndom.__iter__c                 C   sx   | j dkr!t }t| j|t|d }|tjkrt|j	
 S d S | j dkr:| jD ]}|j|kr9t|j
   S q)d S r   )rC   r   r   pmdaCacheLookuprB   r   rJ   PMDA_CACHE_ACTIVEstrvaluedecoderD   r9   r:   )r.   instancer>   stsrO   r   r   r   rM      s   





zpmdaIndom.inst_name_lookupc                 C   s    t |trt|tj d S d S r'   )
isinstancedictr   rI   rJ   PMDA_CACHE_LOADrG   r   r   r   rE      s   
zpmdaIndom.load_indomc                 C   s"   | j dkrt| jtj d S d S )N)rC   r   rI   rB   rJ   r[   r0   r   r   r   load   s   
zpmdaIndom.loadc                 C   sX   t |}t|  }t|D ]}|| j|| _|| j|| _q|| _|| _t  d S r'   )	lenr8   rN   r9   r:   rD   rC   rJ   set_need_refresh)r.   rH   instance_countinstance_arrayrP   r   r   r   set_list_instances   s   
zpmdaIndom.set_list_instancesc              	   C   sX   t |tj | D ]}|d}t |tj|t||  qt |tj	 d| _
d S )Nr;   r\   )r   rI   rJ   PMDA_CACHE_INACTIVEkeysr<   pmdaCacheStorePMDA_CACHE_ADDr   PMDA_CACHE_SAVErC   )r.   r+   rH   keykey8r   r   r   set_dict_instances   s   

zpmdaIndom.set_dict_instancesc                 C   sJ   |d u r	d| _ d S t|trd| _ | || d S t|| _ | | d S )Nr   r\   )rC   rY   rZ   rj   r^   rb   rG   r   r   r   rF      s   


zpmdaIndom.set_instancesc                 C   r?   )Nz pmdaIndom@%#lx indom=%#lx num=%d)r   rB   rC   r0   r   r   r   r1      r@   zpmdaIndom.__str__c                 C   s8   | j dkrt| jtj}|dk rt|d S ttjr   )	rC   r   rI   rB   rJ   r[   r   cpmapi
PM_ERR_NYI)r.   rX   r   r   r   
cache_load   s   

zpmdaIndom.cache_loadc                 C   (   | j dkrt| jtj d S ttjr   )	rC   r   rI   rB   rJ   rS   r   rk   rl   r0   r   r   r   cache_mark_active      

zpmdaIndom.cache_mark_activec                 C   rn   r   )	rC   r   rI   rB   rJ   rc   r   rk   rl   r0   r   r   r   cache_mark_inactive   rp   zpmdaIndom.cache_mark_inactivec                 C   s6   | j dkrt| j|}|dk rt|d S ttjr   )rC   r   pmdaCacheResizerB   r   rk   rl   )r.   maximumrX   r   r   r   cache_resize   s   

zpmdaIndom.cache_resizeN)r3   r4   r5   r6   r   r
   r   r8   r7   r(   rQ   rM   rE   r]   rb   rj   rF   r1   rm   ro   rq   rt   r   r   r   r   rA      s&    


rA   c                   @   s   e Zd ZdZdd ZdS )	pmdaUnitszF Wrapper class for PMDAs defining their metrics (avoids pmapi import) c              	   C   s   t | |||||| d S r'   )r   r(   )r.   dimSdimTdimCscaleSscaleTscaleCr   r   r   r(      r2   zpmdaUnits.__init__N)r3   r4   r5   r6   r(   r   r   r   r   ru      s    ru   c                   @   s|   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dddZ
dd ZdddZdd Zdd Zdd Zdd ZdS )MetricDispatcha   Helper for PMDA class which manages metric dispatch
        table, metric namespace, descriptors and help text.

        Overall strategy is to interface to the C code in
        python/pmda.c here, using a void* handle to the PMDA
        dispatch structure (allocated and managed in C code).

        In addition, several dictionaries for metric related
        strings are managed here (names, help text) - cached
        for quick lookups in callback routines.
    c                 C   sP   g | _ i | _i | _i | _g | _i | _i | _i | _i | _i | _	t
|||| d S r'   )_indomtable_indoms_indom_oneline_indom_helptext_metrictable_metrics_metric_names_metric_names_map_metric_oneline_metric_helptextrJ   init_dispatch)r.   domainr>   logfilehelpfiler   r   r   r(     s   zMetricDispatch.__init__c                 C   s.   | j d d = | j  | j  | j  d S r'   )r}   r~   clearr   r   r0   r   r   r   clear_indoms  s   

zMetricDispatch.clear_indomsc                 C   sB   | j d d = | j  | j  | j  | j  | j  d S r'   )r   r   r   r   r   r   r   r0   r   r   r   clear_metrics0  s   



zMetricDispatch.clear_metricsc                 C   s   |    t  d S r'   )r   rJ   r_   r0   r   r   r   reset_metrics:  s   zMetricDispatch.reset_metricsc                 C   s   t | j d S r'   )rJ   pmns_refreshr   r0   r   r   r   r   A  s   zMetricDispatch.pmns_refreshc                 C      t   d S r'   )rJ   connect_pmcdr0   r   r   r   r   D  s   zMetricDispatch.connect_pmcd c                 C   sz   |j j}|| jv rtd| || jv rtd| j| || j|< || j|< || j|< || j|< || j	|< t
  d S )Nz.attempt to add_metric with an existing name=%sz+attempt to add_metric with an existing PMID)r&   r)   r   KeyErrorr   r   appendr   r   r   rJ   r_   )r.   r>   metriconelinetextr)   r   r   r   
add_metricG  s   






zMetricDispatch.add_metricc                 C   s   |j j}|| jvrtd| || jvrtd| j| | j| | j| | j| | j	| | j
| t  d S )Nz-attempt to remove non-existant metric name=%sz/attempt to remove_metric with non-existant PMID)r&   r)   r   r   r   r   removepopr   r   r   rJ   r_   )r.   r>   r   r)   r   r   r   remove_metricV  s   

zMetricDispatch.remove_metricc                 C   sR   |j }| jD ]}|j |krtdq| j| || j|< || j|< || j|< d S )Nz(attempt to add_indom with an existing ID)rB   r}   r   r   r~   r   r   )r.   r+   r   r   indomidentryr   r   r   	add_indome  s   



zMetricDispatch.add_indomc                 C   sh   t |tr|j}|}n|}t||}t |tr-t| jD ]\}}|j|kr,|| j|<  nq|| j|< d S r'   )rY   rA   rB   list	enumerater}   r~   )r.   r+   rH   rB   replacementrP   r   r   r   r   replace_indomo  s   




zMetricDispatch.replace_indomc                 C   s@   | j | }|jdk rt }t||dt|}|tjkr|S dS )z
        Lookup the value associated with an (internal) instance ID
        within a specific instance domain (only valid with indoms
        of cache type - array indom will always return None).
        r   N)r~   rC   r   r   rR   r   rJ   rS   )r.   r+   rW   r   rU   rX   r   r   r   inst_lookup  s   


zMetricDispatch.inst_lookupc                 C   s   | j | }||S )zv
        Lookup the name associated with an (internal) instance ID within
        a specific instance domain.
        )r~   rM   )r.   r+   rW   r   r   r   r   rM     s   

zMetricDispatch.inst_name_lookupc                 C   s2   z| j t|| }W |S  ty   d}Y |S w )zR
        Lookup the name associated with a performance metric identifier.
        N)r   rJ   	pmda_pmidr   )r.   clusteritemr>   r   r   r   pmid_name_lookup  s   zMetricDispatch.pmid_name_lookupN)r   r   )r3   r4   r5   r6   r(   r   r   r   r   r   r   r   r   r   r   rM   r   r   r   r   r   r|      s    



r|   c                   @   s  e Zd ZdZdd Zdd ZeedddZeedddZdGddZ	d	d
 Z
dd Zdd Zdd Zdd Zedd Zedd Zedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Z ed5d6 Z!ed7d8 Z"ed9d: Z#ed;d< Z$ed=d> Z%ed?d@ Z&edAdB Z'edCdD Z(edEdF Z)dS )HPMDAzj Defines a PCP performance metrics domain agent
        Used to add new metrics into the PCP toolkit.
    c                 C      | j S )z  Property for name of this PMDA )_namer0   r   r   r   	read_name     zPMDA.read_namec                 C   r   )z0 Property for unique domain number of this PMDA )_domainr0   r   r   r   read_domain  r   zPMDA.read_domainNc                 C   sL   || _ || _|s|d }d| }|sdtd|f }t| |||| d S )Nz.logpmdaz
%s/%s/helpPCP_PMDAS_DIR)r   r   PCPpmGetConfigr|   r(   )r.   r>   r   r   r   pmdanamer   r   r   r(     s   zPMDA.__init__c                 C   s   t d| j | jf  dS )zH
        Write out the domain.h file (used during installation)
        z#define %s %dN)printr   upperr   r0   r   r   r   domain_write  s   zPMDA.domain_writec                    sf   | j   fdd D }|dk}d}|rd}td |D ]}td||| jf  q|r1td d	S d	S )
zI
        Write out the namespace file (used during installation)
        c                    s   h | ]} |  d d qS ).r   )split).0rh   pmnsr   r   	<setcomp>  s    z"PMDA.pmns_write.<locals>.<setcomp>rootr   	zroot {z%s%s	%d:*:*}N)r   r   r   )r.   r   prefixesindentleadprefixr   r   r   
pmns_write  s   zPMDA.pmns_writec                 C      t   dS )zF
        Tell PMCD the PMDA is not ready to process requests.
        N)rJ   pmda_notreadyr0   r   r   r   r        zPMDA.pmda_notreadyc                 C   r   )zB
        Tell PMCD the PMDA is ready to process requests.
        N)rJ   
pmda_readyr0   r   r   r   r     r   zPMDA.pmda_readyc                 C   s   dt jv r|   dS dt jv r| t jd  dS |   t| j t| j	 t
| j t| j t| j| j dS )a  
        All the real work happens herein; we can be called in one of three
        situations, determined by environment variables.  First couple are
        during the agent Install process, where the domain.h and namespace
        files need to be created.  The third case is the real mccoy, where
        an agent is actually being started by pmcd/dbpmda and makes use of
        libpcp_pmda to talk PCP protocol.
        PCP_PYTHON_DOMAINPCP_PYTHON_PMNSN)osenvironr   r   r   rJ   pmid_oneline_refreshr   pmid_longtext_refreshr   indom_oneline_refreshr   indom_longtext_refreshr   pmda_dispatchr}   r   r0   r   r   r   run  s   
	
zPMDA.runc                 C   
   t | S r'   )rJ   	set_fetch)fetchr   r   r   r        
zPMDA.set_fetchc                 C   r   r'   )rJ   	set_label)r   r   r   r   r     r   zPMDA.set_labelc                 C   r   r'   )rJ   	set_notes)notesr   r   r   r   	  r   zPMDA.set_notesc                 C   r   r'   )rJ   set_refresh)refreshr   r   r   r     r   zPMDA.set_refreshc                 C   r   r'   )rJ   set_instance)rW   r   r   r   r     r   zPMDA.set_instancec                 C   r   r'   )rJ   set_fetch_callback)fetch_callbackr   r   r   r     r   zPMDA.set_fetch_callbackc                 C   r   r'   )rJ   set_label_callback)label_callbackr   r   r   r     r   zPMDA.set_label_callbackc                 C   r   r'   )rJ   set_notes_callback)notes_callbackr   r   r   r     r   zPMDA.set_notes_callbackc                 C   r   r'   )rJ   set_attribute_callback)attribute_callbackr   r   r   r   !  r   zPMDA.set_attribute_callbackc                 C   r   r'   )rJ   set_store_callback)store_callbackr   r   r   r   %  r   zPMDA.set_store_callbackc                 C   r   r'   )rJ   set_endcontext_callback)endcontext_callbackr   r   r   r   )  r   zPMDA.set_endcontext_callbackc                 C   r   r'   )rJ   set_refresh_all)refresh_allr   r   r   r   -  r   zPMDA.set_refresh_allc                 C   r   r'   )rJ   set_refresh_metrics)refresh_metricsr   r   r   r   1  r   zPMDA.set_refresh_metricsc                   C   r   r'   )rJ   set_notify_changer   r   r   r   r   5     zPMDA.set_notify_changec                 C   r   r'   )rk   pmSetProcessIdentity)usernamer   r   r   set_user9  r   zPMDA.set_userc                 C      t | |S r'   )rJ   r   )r   r   r   r   r   r)   =  r   z	PMDA.pmidc                 C   s   t | ||S r'   )rJ   
pmid_build)r   r   r   r   r   r   r   A  s   zPMDA.pmid_buildc                 C   r   r'   )rJ   pmid_cluster)r   r   r   r   r   E  r   zPMDA.pmid_clusterc                 C   r   r'   )rJ   
pmda_indom)serialr   r   r   r+   I  r   z
PMDA.indomc                 C   r   r'   )rJ   indom_build)r   r   r   r   r   r   M  r   zPMDA.indom_buildc                 C   s   t | |||||S r'   )rJ   
pmda_units)	dim_spacedim_time	dim_countscale_space
scale_timescale_countr   r   r   r-   Q  s   z
PMDA.unitsc                 C   r   r'   )rJ   pmda_uptime)nowr   r   r   uptimeU  r   zPMDA.uptimec                 C   r   r'   )rJ   pmda_set_comm_flags)r    r   r   r   set_comm_flagsY  r   zPMDA.set_comm_flagsc                 C   r   r'   )rJ   pmda_logmessager   r   r   log]  r   zPMDA.logc                 C   r   r'   )rJ   pmda_dbgr  r   r   r   dbga  r   zPMDA.dbgc                 C   r   r'   )rJ   pmda_errr  r   r   r   erre  r   zPMDA.err)NN)*r3   r4   r5   r6   r   r   propertyr>   r   r(   r   r   r   r   r   staticmethodr   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   )-r6   r   rk   rJ   	pcp.pmapir   r   r   r   r   r   r   ctypes.utilr   ctypesr	   r
   r   r   r   r   r   r   r   r   re   restypeargtypespmdaCacheStoreKeyrR   pmdaCacheLookupNamepmdaCacheLookupKeyrI   rr   r   r   r!   r"   r$   r8   rA   ru   objectr|   r   r   r   r   r   <module>   s`    

r
 %