
    bj                         d 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mZ ddl	m
Z
 ddlmZ  ej                  e      ZdZdZdd	Zdd
	 	 	 	 	 	 	 	 	 ddZy)uA  Anthropic kullanım istatistiklerini structured JSON-lines log'a yazan modül.

Mimari:
    Her `messages.create` / `messages.stream` çağrısından sonra `record_usage`
    çağrılır. JSONL formatında /var/log/patentyazar-llm-usage.log (production)
    veya /tmp/llm-usage.log (development) dosyasına atomic append yapar.

Laravel tarafında `php artisan llm:ingest-usage` cron komutu bu dosyayı okur,
`llm_usage_records` tablosuna ekler ve dosyayı truncate eder.

Bu yüzden file-based loglama tercih ettik (Redis pub-sub veya başka bir kanal
yerine):
  - Python ve Laravel ayrı süreçlerde, file ortak alan
  - Apache + systemd standart, bir yere bağımlılık eklemek istemiyoruz
  - Append atomic (POSIX < PIPE_BUF, log satırları küçük)
  - Cron-based ingest 5 dakikada bir → admin paneli için zaten yeterli
    )annotationsN)Path)Any)get_settingsz"/var/log/patentyazar-llm-usage.logz/tmp/llm-usage.logc                 J   t               } t        | dd      }|r|S t        t              }|j	                         r0t        j                  |t
        j                        rt        S t        S t        j                  |j                  t
        j                        rt        S t        S )zIConfigured log path; production'da /var/log/ user yazabiliyor mu kontrol.llm_usage_log_pathN)
r   getattrr   _DEFAULT_LOG_PATHexistsosaccessW_OKparent_DEV_LOG_PATH)settings	candidatelog_files      9/var/www/ai.patentyazar.com/app/services/llm/usage_log.py	_log_pathr   &   s|    ~H"6=I %&H99Xrww'$$  
8??BGG	,      )extrac           	        	 ydfd}t        t        j                         dz        | | |d       |d       |d       |d      d}|r||d	<   t        j                  |d
d      dz   }t	        t               dd      5 }|j                  |       ddd       y# 1 sw Y   yxY w# t        $ r t        j                  d       Y yw xY w)u  Anthropic response'undaki `usage` objesini log'a yazar.

    `usage` Anthropic SDK'nın `Usage` modeli olabilir veya stream end_event'inden
    gelmiş bir dict olabilir. İki tipten de aşağıdaki alanları çeker:

      input_tokens                     — non-cached input
      output_tokens                    — completion
      cache_creation_input_tokens      — yeni cache write (5min veya 1h)
      cache_read_input_tokens          — cache hit (en ucuz)

    Bu alanların hepsi int. Eksik olan 0 sayılır.

    `endpoint` log'lama için string identifier — örn. "drafting.stream",
    "intake.suggest", "prior_art.analyze". Admin paneli endpoint bazında
    grupluyor.

    Hatalar yutulur — logging code uygulama akışını hiçbir zaman bozmamalı.
    Nc                    t        |       rt        t        |       xs d      S t        t              rt        j                  | d      xs d      S y)Nr   )hasattrintr	   
isinstancedictget)keyusages    r   _getzrecord_usage.<locals>._get\   sL    uc"75#.3!44%&599S!,122r   i  input_tokensoutput_tokenscache_creation_input_tokenscache_read_input_tokens)tsmodelendpointr"   r#   r$   r%   r   F),:)ensure_ascii
separators
azutf-8)encodingz!LLM usage log failed (suppressed))r   strreturnr   )
r   timejsondumpsopenr   write	Exception_logger	exception)r'   r    r(   r   r!   recordlinefs    `      r   record_usager=   ?   s    2!?=	 diikD()  0!/2+/0M+N'+,E'F"
 #F7Ozz&uLtS )+sW5 	GGDM	 	 	  ? 	=>?s5   B+ A>B+ BB+ B($B+ (B+ +CC)r1   r0   )
r'   r0   r    r   r(   r0   r   zdict[str, Any] | Noner1   None)__doc__
__future__r   r3   loggingr   r2   pathlibr   typingr   
app.configr   	getLogger__name__r8   r
   r   r   r=    r   r   <module>rH      s   $ #   	    #
'

H
% 9 $< $(:?:? :? 	:?
 !:? 
:?r   