o
    i+                  	   @   s  d dl Z d dl mZ d dl m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	 d dlm
Z
 d dlmZ d dlZd dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! ddlm"Z" ddlm#Z# ddlm$Z$ ddlm%Z% ddlm&Z& ddlm'Z' ddlm(Z( ddlm)Z) ddlm*Z* e+dZ,e+d Z-d!e
d"efd#d$Z.d%ed&e/e0e	f d"dfd'd(Z1d%ed"dfd)d*Z2d"ee fd+d,Z3d-ed"dfd.d/Z4dFd-ed0e0d1e	d"dfd2d3Z5d4e0fd5d6Z6d7e0d"e0fd8d9Z7d:e/d"e/e0e	f fd;d<Z8d=e	d"e jfd>d?Z9dGd=e	dAe:d"e;e fdBdCZ<dDdE Z=dS )H    N)	Parameter)	Signature)Any)Callable)Optional)get_runtime_context)MAX_SPAN_META_VALUE_LEN)Context)Span)_AI_OBS_ENABLED_KEY)_DJM_ENABLED_KEY)_FILTER_KEPT_KEY)_SAMPLING_PRIORITY_KEY)_SPAN_MEASURED_KEY)_TraceContext   )DD_RAY_TRACE_CTX)RAY_ACTOR_ID)RAY_COMPONENT)RAY_HOSTNAME)
RAY_JOB_ID)RAY_METADATA_PREFIX)RAY_NODE_ID)RAY_SUBMISSION_ID)RAY_SUBMISSION_ID_TAG)RAY_TASK_ID)RAY_WORKER_ID)REDACTED_PATH)REDACTED_VALUEz2^job\:([A-Za-z0-9_\.\-]+),run:([A-Za-z0-9_\.\-]+)$z([^\s\/\\]+)\.pymethodreturnc                 C   sX   t | }t|jv r|S tttjd d}t|j |g }t|dd d}|j	|dS )N)defaultc                 S   s   | j tjkS N)kindr   VAR_KEYWORD)p r&   V/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/contrib/internal/ray/utils.py<lambda>9   s    z,_inject_dd_trace_ctx_kwarg.<locals>.<lambda>)key)
parameters)
inspect	signaturer   r*   r   KEYWORD_ONLYlistvaluessortedreplace)r   old_sig	new_paramparams_listsorted_paramsr&   r&   r'   _inject_dd_trace_ctx_kwarg2   s   

r6   contextkwargsc                 C   s<   i }t | | d|vs|d d u ri |d< ||d t< d S )Nr8   )r   _injectr   )r7   r8   headersr&   r&   r'   _inject_context_in_kwargs=   s
   r;   c                 C   s8   i }t | | |ddtjd< |ddtjd< d S )Ntraceparent 
tracestate)r   r9   getosenviron)r7   r:   r&   r&   r'   _inject_context_in_envE   s   rB   c                   C   sD   t jdd ur t jdd ur tt jdt jddS d S )Nr<   r>   )r<   r>   )r@   rA   r?   r   _extractr&   r&   r&   r'   !_extract_tracing_context_from_envL   s    

rD   spanc                 C   s  |  dt |  tt  | td | td | td | t	d | t
d tjt}|d ur<|  t| t rt }|  t|  |  t|  | }|d ura|  t| |jjtjjjkrx| }|d urx|  t| | }|d ur|  t | d S d S d S )N	componentr      )!_set_tag_strr   r   socketgethostname
set_metricr   r   r   r   r   r@   rA   r?   r   r   rayis_initializedr   r   
get_job_idr   get_node_idget_worker_idr   workermode_privateWORKER_MODEget_task_idr   get_actor_idr   )rE   submission_idruntime_context	worker_idtask_idactor_idr&   r&   r'   !_inject_ray_span_tags_and_metricsW   s4   r\   tag_name	tag_valuec                 C   s.   t |tkr| |t dS | || dS )zWe want to add args/kwargs values as tag when we execute a task/actor method.
    However they might be really big. In that case we dont way to serialize them AT ALL
    and we do not want to rely on _encoding.pyx.
    N)sys	getsizeofr   set_tagr   )rE   r]   r^   r&   r&   r'   set_tag_or_truncatex   s   rb   
entrypointc                 C   s   t | }|r|dS dS )z/
    Get the job name from the entrypoint.
    r   N)ENTRY_POINT_REGEXsearchgroup)rc   matchr&   r&   r'   get_dd_job_name_from_entrypoint   s   

rh   sc                    s>   dd  dt f fddtd| }dfdd	|D S )
z
    Redact path-like substrings from an entry-point string.
    Uses os.sep (and os.altsep if present) to detect paths; preserves spacing.
    c                 S   sb   t j| v rt jnt jrt j| v rt jnd}|s| S | |}|s"tS ||d }t | | S )z
        If s contains a path separator, replace the directory part with REDACTION,
        preserving the final component (basename). Trailing separators are ignored.
        Detects both os.sep and os.altsep if present.
        N)r@   sepaltseprstripr   split)ri   used_sepcorebasenamer&   r&   r'   _redact_pathlike   s   *
z&redact_paths.<locals>._redact_pathliker    c                    s   d| v r@|  dd\}}t|dkr7|d |d kr7|d dv r7|d }|dd }| d|  | | S | d | S t| dkrh| d | d krh| d dv rh| d }| dd }|  | | S  | S )N=r   rG   r   rj   >   "')rn   len)tokr)   valqinner)rr   r&   r'   _redact_token   s   ((z#redact_paths.<locals>._redact_tokenz(\s+)r=   c                 3   s(    | ]}|  d kr|n |V  qdS )r=   N)strip).0part)r{   r&   r'   	<genexpr>   s   & zredact_paths.<locals>.<genexpr>)strrern   join)ri   partsr&   )rr   r{   r'   redact_paths   s   r   datac                    s.   t | tsi S i  fdd  | t S )a  
    Converts a JSON (or Python dictionary) structure into a dict mapping
    dot-notation paths to leaf values, with keys prefixed once by RAY_METADATA_PREFIX.

    - Assumes the top-level is a dictionary. If a list is encountered anywhere,
      it is stringified with json.dumps and treated as a leaf (no recursion into list elements).
    - Leaf values (str, int, float, bool, None) are returned as-is as the dict values.
    - Returned dict keys are prefixed once with RAY_METADATA_PREFIX.
    c                    s   t | tr |  D ]\}}|r| d| n|} || q	d S t | tr@z	tj| dd}W n ty9   d}Y nw ||< d S | |< d S )N.F)ensure_asciiz[])
isinstancedictitemsr.   jsondumps	Exception)nodepathr)   valuenew_path	list_dump_recurseresultr&   r'   r      s   

z'flatten_metadata_dict.<locals>._recurse)r   r   r   )r   r&   r   r'   flatten_metadata_dict   s   

r   funcc                    sh   t  r/g d}t fdd|D r( }dd  |D ]}t |t|| qnt dt S )aB  Get signature parameters.

    Support Cython functions by grabbing relevant attributes from the Cython
    function and attaching to a no-op function. This is somewhat brittle, since
    inspect may change, but given that inspect is written to a PEP, we hope
    it is relatively stable. Future versions of Python may allow overloading
    the inspect 'isfunction' and 'ismethod' functions / create ABC for Python
    functions. Until then, it appears that Cython won't do anything about
    compatibility with the inspect module.

    Args:
        func: The function whose signature should be checked.

    Returns:
        A function signature object, which includes the names of the keyword
            arguments as well as their default values.

    Raises:
        TypeError: A type error if the signature is not supported
    )__code____annotations____defaults____kwdefaults__c                 3   s    | ]}t  |V  qd S r"   )hasattr)r}   attrr   r&   r'   r      s    z get_signature.<locals>.<genexpr>c                   S   s   d S r"   r&   r&   r&   r&   r'   r     s   zget_signature.<locals>.funcz( is not a Python function we can process)	is_cythonallsetattrgetattr	TypeErrorr+   r,   )r   attrsoriginal_funcr   r&   r   r'   get_signature   s   
r   Fignore_firstc                 C   sD   t t| j }|r t|dkrtd| j d|dd }|S )a\  Extract the function signature from the function.

    Args:
        func: The function whose signature should be extracted.
        ignore_first: True if the first argument should be ignored. This should
            be used when func is a method of a class.

    Returns:
        list of Parameter objects representing the function signature.
    r   z5Methods must take a 'self' argument, but the method 'z' does not have one.r   N)r.   r   r*   r/   rv   
ValueError__name__)r   r   signature_parametersr&   r&   r'   extract_signature  s   r   c                 C   s$   dd }|| pt | do|| jS )z1Check if an object is a Cython function or methodc                 S   s   t | jdkS )Ncython_function_or_method)typer   )xr&   r&   r'   check_cython+  s   zis_cython.<locals>.check_cython__func__)r   r   )objr   r&   r&   r'   r   $  s   r   r"   )F)>r+   r   r   r   r@   r   rI   r_   typingr   r   r   rL   ray.runtime_contextr   ddtrace._trace._limitsr   ddtrace._trace.contextr	   ddtrace._trace.spanr
   ddtrace.constantsr   r   r   r   r   ddtrace.propagation.httpr   	constantsr   r   r   r   r   r   r   r   r   r   r   r   r   compileJOB_NAME_REGEXrd   r6   r   r   r;   rB   rD   r\   rb   rh   r   r   r   boolr.   r   r   r&   r&   r&   r'   <module>   sb    

!
/)(