
    h2-                         d dl Z d dlZd dlmZ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  G d
 de	      Zy)    N)datetime	timedelta)Optional)verbose_logger)CustomLogger   )CloudZeroStreamer)LiteLLMDatabase)CBFTransformerc                        e Zd ZdZddee   dee   dee   f fdZddedee   defd	Z	ddedee   fd
Z
ddedee   fdZd ZddZ xZS )CloudZeroLoggeraH  
    CloudZero Logger for exporting LiteLLM usage data to CloudZero AnyCost API.
    
    Environment Variables:
        CLOUDZERO_API_KEY: CloudZero API key for authentication
        CLOUDZERO_CONNECTION_ID: CloudZero connection ID for data submission
        CLOUDZERO_TIMEZONE: Timezone for date handling (default: UTC)
    api_keyconnection_idtimezonec                     t        |   di | |xs t        j                  d      | _        |xs t        j                  d      | _        |xs t        j                  dd      | _        y)zXInitialize CloudZero logger with configuration from parameters or environment variables.CLOUDZERO_API_KEYCLOUDZERO_CONNECTION_IDCLOUDZERO_TIMEZONEUTCN )super__init__osgetenvr   r   r   )selfr   r   r   kwargs	__class__s        d/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/integrations/cloudzero/cloudzero.pyr   zCloudZeroLogger.__init__   sZ    "6" @")),?"@*Rbii8Q.R JBII.BE$J    target_hourlimit	operationc                 n  K   	 t        j                  d       | j                  r| j                  st	        d      | j                  ||       d{   }|j                         rt        j                  d       yt        | j                  | j                  | j                        }t        j                  dt        |       d       |j                  ||       t        j                  d	t        |       d       y7 # t        $ r'}t        j                  d
t        |               d}~ww xY ww)a  
        Exports the usage data for a specific hour to CloudZero.

        - Reads spend logs from the DB for the specified hour
        - Transforms the data to the CloudZero format
        - Sends the data to CloudZero
        
        Args:
            target_hour: The specific hour to export data for
            limit: Optional limit on number of records to export (default: 1000)
            operation: CloudZero operation type ("replace_hourly" or "sum")
        z,CloudZero Logger: Starting usage data exportzpCloudZero configuration missing. Please set CLOUDZERO_API_KEY and CLOUDZERO_CONNECTION_ID environment variables.Nz/CloudZero Logger: No usage data found to export)r   r   user_timezonezCloudZero Logger: Transmitting z records to CloudZero)r"   z(CloudZero Logger: Successfully exported z.CloudZero Logger: Error exporting usage data: )r   debugr   r   
ValueError_fetch_cbf_data_for_houris_emptyinfor	   r   lensend_batched	Exceptionerrorstr)r   r    r!   r"   cbf_datastreameres          r   export_usage_dataz!CloudZeroLogger.export_usage_data!   s    	  !OP <<t'9'9  G 
 "::;NNH  "##$UV )"00"mmH   #B3x=/Qf!gh!!(i!@"J3x=/Yn op! O$  	  #QRUVWRXQY!Z[	sH   D5AD D )D ;D5<BD ?D5 D 	D2"D--D22D5c                   K   t               }t        j                  d|        |j                  ||       d{   }|j	                         rt        j
                  d       |S t        j                  dt        |       d       t               }|j                  |      }|j	                         rt        j                  d       |S 7 w)ap  
        Helper method to fetch usage data for a specific hour and transform it to CloudZero CBF format.
        
        Args:
            target_hour: The specific hour to fetch data for
            limit: Optional limit on number of records to fetch (default: 1000)
            
        Returns:
            CBF formatted data ready for CloudZero ingestion
        z.CloudZero Logger: Loading spend logs for hour )r    r!   Nz<CloudZero Logger: No usage data found for the specified hourzCloudZero Logger: Processing  recordsz4CloudZero Logger: No valid data after transformation)
r
   r   r%   get_usage_data_for_hourr(   r)   r*   r   	transformwarning)r   r    r!   databasedatatransformerr/   s          r   r'   z(CloudZeroLogger._fetch_cbf_data_for_hourN   s      #$Mk][\55+UZ5[[==? ^_K<SYKxPQ %&((.""#YZ \s   9CCBCc                   K   	 t        j                  d       | j                  ||       d{   }|j                         rt        j                  d       y| j                  |       t        j                  dt        |       d       y7 ^# t        $ rH}t        j                  dt        |              t        j                  dt        |               d}~ww xY ww)a  
        Only prints the spend logs data for a specific hour that would be exported to CloudZero.
        
        Args:
            target_hour: The specific hour to export data for
            limit: Limit number of records to display (default: 1000)
        z)CloudZero Logger: Starting dry run exportNz&CloudZero Dry Run: No usage data foundz(CloudZero Logger: Dry run completed for r4   z+CloudZero Logger: Error in dry run export: zCloudZero Dry Run Error: )r   r%   r'   r(   r7   _display_cbf_data_on_screenr)   r*   r,   r-   r.   )r   r    r!   r/   r1   s        r   dry_run_export_usage_dataz)CloudZeroLogger.dry_run_export_usage_datam   s     	  !LM "::;NNH  "&&'OP ,,X6"J3x=/Ya bc O  	  #NsSTvh!WX  #<SVH!EF	sE   C#*B B)B C#3B C#B 	C ACC  C#c           
         ddl m} ddlm} ddlm}  |       }|j                         r|j                  d       y|j                  dt        |       d       |j                         } |d	d
|d      }|j                  ddd       |j                  dddd       |j                  dddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |D ]  }t        |j                  dd            }	t        |j                  dd            }
t        |j                  dd            }t        |j                  dd            }t        |j                  dd            }t        |j                  dd            }t        |j                  dd            }|j                  |	|
|||||        |j                  |       t        d  |D              }t        t        d! |D                    }t        t        d" |D                    }t        d# |D              }|j                  d$       |j                  d%t        |      d&       |j                  d'|d(       |j                  d)|d&       |j                  d*|        |j                  d+|        |j                  d,       y)-z<Display CBF transformed data in a formatted table on screen.r   )SIMPLE)Console)Tablez'[yellow]No CBF data to display[/yellow]Nu2   
[bold green]💰 CloudZero CBF Transformed Data (z records)[/bold green]Tz	bold cyan)r   r   )show_headerheader_styleboxpaddingztime/usage_startblueF)styleno_wrap	cost/costgreenright)rG   justifyrH   usage/amountyellowzresource/idmagentaresource/servicecyanresource/accountwhitezresource/regiondimzN/Ac              3   @   K   | ]  }|j                  d d        yw)rI   r   Nget.0records     r   	<genexpr>z>CloudZeroLogger._display_cbf_data_on_screen.<locals>.<genexpr>   s     JK3J   c              3   d   K   | ](  }|j                  d       s|j                  d d       * yw)rR    NrV   rX   s     r   r[   z>CloudZeroLogger._display_cbf_data_on_screen.<locals>.<genexpr>   +     !}^d^h^hi{^|&**-?"D!}   00c              3   d   K   | ](  }|j                  d       s|j                  d d       * yw)rP   r^   NrV   rX   s     r   r[   z>CloudZeroLogger._display_cbf_data_on_screen.<locals>.<genexpr>   r_   r`   c              3   @   K   | ]  }|j                  d d        yw)rM   r   NrV   rX   s     r   r[   z>CloudZeroLogger._display_cbf_data_on_screen.<locals>.<genexpr>   s     OV6::na8Or\   u(   
[bold blue]📊 CBF Summary[/bold blue]z  Records: ,z  Total Cost: $z.2fz  Total Tokens: z  Unique Accounts: z  Unique Services: uM   
[dim]💡 This is the CloudZero CBF format ready for AnyCost ingestion[/dim])rich.boxr?   rich.consoler@   
rich.tablerA   r(   printr*   to_dicts
add_columnr.   rW   add_rowsumset)r   r/   r?   r@   rA   consolerecords	cbf_tablerZ   time_usage_start	cost_costusage_amountresource_idresource_serviceresource_accountresource_region
total_costunique_accountsunique_servicestotal_tokenss                       r   r<   z+CloudZeroLogger._display_cbf_data_on_screen   s   #($)MMCDKCPXM?Zpqr ##% d&Z`a	/vuM[RWX^8WV[\])UK/vuM/wN.eUKF"6::.@%#HIFJJ{A67Ivzz.!<=Lfjj>?K"6::.@%#HI"6::.@%#HI!&**->"FGO    ( 	i  J'JJ
c!}SZ!}}~c!}SZ!}}~ OwOOABCL#345
3'789(a(89:+O+<=>+O+<=>fgr   c                     K   ddl m}  ||      d fd}t        j                   |              t	        j
                  d       yw)z
        Initialize a background job that exports usage data every hour.
        Uses PodLockManager to ensure only one instance runs the export at a time.
        
        Args:
            redis_cache: Redis cache instance for pod locking
        r   )PodLockManager)redis_cachecloudzero_hourly_exportc                    K   	 	 t        j                         } | j                  ddd      }|t        d      z
  }j	                         d {   }|rd	 t        j                  d|        j                  |       d {    t        j                  d|        j                         d {    nt        j                  d       t        j                         t        d      z   j                  ddd      }|t        j                         z
  j                         }t        j                  |       d {    C7 7 7 # j                         d {  7   w xY w7 +# t        $ rI}t        j                  dt        |              t        j                  d	       d {  7   Y d }~vd }~ww xY ww)
Nr   )minutesecondmicrosecondr   )hoursz3CloudZero Background Job: Starting export for hour z4CloudZero Background Job: Completed export for hour zHCloudZero Background Job: Another instance is already running the exportz7CloudZero Background Job: Error in hourly export task: i,  )r   utcnowreplacer   acquire_lockr   r)   r2   release_lockr%   total_secondsasynciosleepr,   r-   r.   )	nowr    lock_acquired	next_hoursleep_secondsr1   
cronjob_idlock_managerr   s	         r   hourly_export_taskz?CloudZeroLogger.init_background_job.<locals>.hourly_export_task   s    -"//+C"%++Qqa+"PK"-	0B"BK +7*C*CJ*O$OM$H*//2efqer0st"&"8"8"EEE*//2fgrfs0tu #/";";J"GGG&,,-wx "*!2YQ5G!G P PXYbcqr P sI%.1B%B$Q$Q$SM!--6663  %P
 F H,";";J"GGG 7  -"((+bcfghcibj)kl!--,,,-s   GAE/ EE/ ,E E
E "E/ 6E7B
E/ E-E/ GE/ 
E E/ E*#E&$E**E/ /	G89F<1F42F<7G<GGz8CloudZero Background Job: Initialized hourly export taskN)6litellm.proxy.db.db_transaction_queue.pod_lock_managerr|   r   create_taskr   r%   )r   r}   r|   r   r   r   s   `   @@r   init_background_jobz#CloudZeroLogger.init_background_job   sF     	
 &+>.
	-D 	.01WXs   A	A)NNN)  replace_hourly)r   )N)__name__
__module____qualname____doc__r   r.   r   r   intr2   r'   r=   r<   r   __classcell__)r   s   @r   r   r      s    K KXc] Kemnqer K+8 +HSM +eh +Z( 8TW= >8 HUXM 8@hD2Yr   r   )r   r   r   r   typingr   litellm._loggingr   "litellm.integrations.custom_loggerr   cz_stream_apir	   r8   r
   r6   r   r   r   r   r   <module>r      s0     	 (  + ; , % %oYl oYr   