
    (<iL*                     J   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mZ ddlmZm	Z	 ddl
mZ ddlmZ ej                  j                  d e ee      j%                         j&                  j&                              Z ee      dz  d	z  Z ee      dz  d
z  Z ee      dz  dz  Z ee      dz  dz  ZdefdZdededee   fdZdde	dedefdZdde	dedefdZde	defdZ de	defdZ!de	defdZ"de	defdZ#d dee	   defdZ$d dedee	   fdZ%d Z&e'dk(  r e&        yy)!u-  
collect_metrics.py — 효과 측정 프레임워크 데이터 수집 스크립트
task-timers.json, git log, memory/reports/, memory/events/에서
메트릭을 수집하여 memory/daily/metrics-YYYY-MM-DD.json에 저장.

weekly-report.py에서 호출 가능하도록 함수 인터페이스 제공.
    N)defaultdict)datetimedate)Path)OptionalWORKSPACE_ROOTmemoryztask-timers.jsonreportseventsdailyreturnc                     t         j                         s$t        dt          t        j                         i S 	 t        t         dd      5 } t        j                  |       }ddd       j                  di       S # 1 sw Y   xY w# t        j                  t        f$ r*}t        d| t        j                         i cY d}~S d}~ww xY w)	u   task-timers.json 로드u'   [WARN] task-timers.json 파일 없음: filerutf-8encodingNtasksu'   [WARN] task-timers.json 로드 실패: )TASK_TIMERS_PATHexistsprintsysstderropenjsonloadgetJSONDecodeErrorOSError)frawes      H/home/jay/workspace/.worktrees/task-2057-dev2/scripts/collect_metrics.pyload_task_timersr%      s    ""$78H7IJQTQ[Q[\	"C': 	a))A,C	www##	 	   '* 7s;#**M	s5   B A<"B <BB C!C CCsinceuntilc                 X   ddddd|  d| g}	 t        j                  |t        ddd	      }|j                  d
k7  rEt	        d|j                   d|j
                  j                          t        j
                         g S |j                  j                         D cg c]#  }|j                         s|j                         % }}|S c c}w # t        $ r  t	        dt        j
                         g cY S t        $ r*}t	        d| t        j
                         g cY d}~S d}~ww xY w)uR   git log --all --oneline --since --until 실행 후 커밋 메시지 목록 반환.gitlogz--allz	--onelinez--since=z--until=TF)cwdcapture_outputtextshellr   u"   [WARN] git log 실패 (returncode=): r   u0   [WARN] git 명령어를 찾을 수 없습니다.u   [WARN] git log 실행 오류: N)
subprocessrunr   
returncoder   r   stripr   stdout
splitlinesFileNotFoundErrorr    )r&   r'   cmdresultlinelinesr#   s          r$   _run_git_logr;   )   s    	ug{
5'
5'C

 !6v7H7H6IV]]M`M`MbLcdknkukuvI*0--*B*B*DU$

UU V @szzR	 .qc2D	sB   A1C C C
4C
C 
C &D)7D)?D$D)$D)target_datedaysc                   	 | j                         }ddlm} |  ||      z   j                         }t        ||      }g d}d}|D ]9  }d|v r||j	                  d      dz   d n|	t        	fd|D              s5|dz  }; |d	d
S )u3   M-1: git log에서 merge conflict 커밋 수 수집r   	timedeltar=   )CONFLICTzMerge conflictzmerge conflict    Nc              3   &   K   | ]  }|v  
 y wN ).0kwmsgs     r$   	<genexpr>z*collect_merge_conflicts.<locals>.<genexpr>R   s     5RrSy5s   u   머지 충돌 발생 횟수valuedescription)	isoformatr   r@   r;   findany)
r<   r=   r&   r@   r'   r:   conflict_keywordscountr9   rJ   s
            @r$   collect_merge_conflictsrT   E   s    !!#E"9$//::<E&EHE +.$;d499S>A%&'D5#455QJE	 4     c                 p   ddl m} | j                         }|  ||      z   j                         }t        ||      }t	        |      }d}|D ]I  }d|v r%||j                  d      dz   d j                         n|j                         }	d|	v sd|	v sE|dz  }K |dkD  rt        ||z  d	z  d
      nd}
|||
ddS )u7   M-2: git log에서 revert/cherry-pick 커밋 수 수집r   r?   rA   rC   rD   Nrevertzcherry-pickd              u   기능 원복 발생률)rM   total_commitsrate_pctrN   )r   r@   rO   r;   lenrP   lowerround)r<   r=   r@   r&   r'   r:   r[   revert_countr9   rJ   r\   s              r$   collect_revertsra   [   s    "!!#E9$//::<E&EJML 36$;d499S>A%&'--/DJJLs?ms2AL
 BOQRARul]2S81=X[H &0	 rU   c                 |   t               }| j                         }d}t        t              }|j	                         D ][  }|j                  d      dk7  r|j                  dd      }|s-	 |dd }||k(  r$|dz  }|j                  d	d
      }||xx   dz  cc<   ] |t        |      ddS # t        t        f$ r Y ~w xY w)u@   M-3: task-timers.json에서 해당 날짜 완료 task 수 수집r   status	completedend_time N
   rD   team_idunknownu   일일 완료 task 수)rM   by_teamrN   )	r%   rO   r   intvaluesr   
ValueError	TypeErrordict)	r<   r   date_strrS   rj   taskre   end_date_strrh   s	            r$   collect_daily_completedrs   s   s    E$$&HE)#.G 88H,88J+	#CR=Lx'
((9i8 A% " =/  I& 		s   *.B))B;:B;c                    d}| j                         }t        j                         rt        j                  d      D ]  }|j	                         s|j
                  }d}||v rd}nQ	 t        j                  |j                         j                        }|j                         j                         |k(  rd}|s}	 |j                  dd      }d|v r|d	z  } d}	t         j                         rt         j#                  d      D ]g  }
|
j	                         s	 t        j                  |
j                         j                        }|j                         j                         |k(  r|	d	z  }	i ||	ddS # t        $ r Y w xY w# t        $ r,}t        d
| d| t        j                         Y d}~vd}~ww xY w# t        $ r Y w xY w)u   M-5: QC FAIL 횟수 수집r   *FTr   replace)r   errorsFAILrD   u'   [WARN] 보고서 파일 읽기 실패 (r/   r   Nz*.retry_countu   QC FAIL 횟수)rM   retry_count_filesrN   )rO   REPORTS_DIRr   rglobis_filenamer   fromtimestampstatst_mtimer   r    	read_textr   r   r   
EVENTS_DIRglob)r<   
fail_countrp   report_filefnamefile_date_matchmtimecontentr#   ry   
event_files              r$   collect_qc_failsr      s   J$$&H &,,S1 	fK&&(  $$E#O5 "&$22;3C3C3E3N3NOEzz|--/8;*. #f%///SW$!OJ3	f< $///: 	J%%' ..z/@/I/IJ::<))+x7%*%	 .' 7    f?}CPQsSZ]ZdZdeef  s>   &AE3:FAF:3	E?>E?	F7!F22F7:	GGc                 t   d}| j                         }t        j                         rt        j                  d      D ]g  }|j	                         s	 t        j                  |j                         j                        }|j                         j                         |k(  r|dz  }i |ddS # t        $ r Y zw xY w)u$   M-6: G1 게이트 FAIL 횟수 수집r   z	*.g1-failrD   u   G1 게이트 FAIL 횟수rL   )rO   r   r   r   r|   r   r~   r   r   r   r    )r<   rS   rp   r   r   s        r$   collect_g1_failsr      s    E$$&H$//+6 	J%%' ..z/@/I/IJ::<))+x7QJE	 1   s   AB++	B76B7c           	      4   t               }| j                         }d}d}|j                         D ]u  }|j                  d      dk7  r|j                  dd      }|s-	 |dd }||k7  r9	 |j                  d	      }|sN|j                  d
      }	|	b	 |t        |	      z  }|dz  }w t        |d      d|ddS # t        t
        f$ r Y w xY w# t        t
        f$ r;}
t        d|j                  dd       d|
 t        j                         Y d}
~
d}
~
ww xY w)u   M-7: 외부 AI 비용 합산rZ   r   rc   rd   re   rf   Nrg   token_usagecost_estimate_usdrD   u"   [WARN] 비용 파싱 오류 (task=task_id?r/   r      USDu   외부 AI 총 비용)rM   currency
task_countrN   )r%   rO   rl   r   rm   rn   floatr   r   r   r_   )r<   r   rp   
total_costr   rq   re   rr   r   costr#   s              r$   collect_ai_costr      sN   E$$&HJJ j88H,88J+	#CR=Lx' (
 hh}-23<	j%+%J!OJ+j4 z1% -	  I& 		 I& 	j6txx	37O6PPSTUSVW^a^h^hii	js*   
B8C8C
	C
D1DDc                 X   | t        j                         } | j                         t        j                         j                  d      | j                         | j                         dt        |       t        |       t        |       t        |       t        |       t        |       dd}|S )u>   모든 메트릭 수집 (weekly-report.py에서 호출 가능)seconds)timespec)startend)zM-1_merge_conflictszM-2_revert_countzM-3_daily_completed_taskszM-5_qc_fail_countzM-6_g1_fail_countzM-7_total_ai_cost)r   collected_atperiodmetrics)r   todayrO   r   nowrT   ra   rs   r   r   r   )r<   r8   s     r$   collect_allr   	  s    jjl %%' 00)0D **,((*

 $;;#G / <)@)M!1+!>!1+!>!0!=
F  MrU   datac                    |t        j                         }t        j                  dd       t        d|j	                          dz  }t        |dd      5 }t        j                  | |d	d
       ddd       |S # 1 sw Y   |S xY w)u8   결과를 memory/daily/metrics-YYYY-MM-DD.json에 저장NT)parentsexist_okzmetrics-z.jsonwr   r   rY   Findentensure_ascii)r   r   
OUTPUT_DIRmkdirrO   r   r   dump)r   r<   out_pathr!   s       r$   save_metricsr   !  s}    jjlTD1h{'<'<'>&?uEEH	hg	. 9!		$!%89O9Os   A;;Bc                      t        j                  d      } | j                  dt        d d       | j                  dt        dd       | j                  d	d
d       | j                         }|j                  rt        j                  |j                        nt        j                         }t        |      }|j                  r"t        t        j                  |dd             y t        ||      }t        d|        y )Nu.   효과 측정 프레임워크 데이터 수집)rN   z--dateu1   수집 대상 날짜 (YYYY-MM-DD, 기본: 오늘))typedefaulthelpz--daysrD   u    수집 기간 일수 (기본: 1)z	--dry-run
store_trueu$   수집만 하고 저장하지 않음)actionr   rY   Fr   u   [OK] 메트릭 저장 완료: )argparseArgumentParseradd_argumentstrrk   
parse_argsr   fromisoformatr   r   dry_runr   r   dumpsr   )parserargstargetr   paths        r$   mainr   ,  s    $$1abF
sD?rs
sA<^_
L?efD.2iiT		*TZZ\FvD||djjae<=D&).tf56rU   __main__)rD   rF   )(__doc__r   r   osr0   r   collectionsr   r   r   pathlibr   typingr   environr   r   __file__resolveparentr   r   rz   r   r   ro   r%   listr;   rk   rT   ra   rs   r   r   r   r   r   r   __name__rG   rU   r$   <module>r      s     	  
 # #   0#d8n6L6L6N6U6U6\6\2]^'(25GG >"X-	9.!H,x7
.!H,w6
$  C DI 8 S  , S  0 $ >5$ 54 5p$ 4 ,& &$ &RXd^ t 0t (4. 7" zF rU   