
    ,Wi                         S r SSKrSSKrSSKrSSKJr  SSKJrJr  SSK	J	r	  \R                  " \5      r " S S5      rg)uC   
日志管理服务

负责日志文件的分类、移动和管理
    N)Path)OptionalList)datetimec                       \ rS rSrSrSS\4S jjrS\S\S\\   4S jrSS\S
\\   S\\   4S jjr	SS\
S\
S\\   4S jjrSS\S\4S jjrS\S\\   4S jrSrg	)
LogManager   u   日志管理器base_log_dirc                     [        U5      U l        U R                  S-  U l        U R                  R                  SSS9  g)uF   
初始化日志管理器

Args:
    base_log_dir: 基础日志目录
failedTparentsexist_okN)r   r
   failed_log_dirmkdir)selfr
   s     J   /Users/yu22x/Desktop/ddd_副本128/ctf/app/services/storage/log_manager.py__init__LogManager.__init__   s=     !."//(:!!$!>    log_filechallenge_output_dirreturnc                    U(       a$  [         R                  R                  U5      (       d  [        R	                  SU 35        g [        U5      n[        U5      nUS-  nUR                  SSS9  XSR                  -  n[        R                  " [        U5      [        U5      5        [        R                  SU 35        U R                  X55        [        U5      $ ! [         a!  n[        R                  SU 3SS9   SnAgSnAff = f)	u   
将日志文件移动到题目目录

Args:
    log_file: 原始日志文件路径
    challenge_output_dir: 题目输出目录
    
Returns:
    新的日志文件路径，如果移动失败则返回None
   日志文件不存在: NlogsTr   u&   已移动日志文件到题目目录: u)   移动日志文件到题目目录失败: exc_info)ospathexistsloggerwarningr   r   nameshutilmovestrinfo_move_related_logs	Exceptionerror)r   r   r   log_pathchallenge_dirchallenge_log_dirnew_log_pathes           r   move_log_to_challenge LogManager.move_log_to_challenge   s     rww~~h77NN4XJ?@	H~H !56M !. 6##D4#@ -}}<LKKHs<'89KK@OP ##H@|$$ 	LLDQCHSWLX	s   BC 
D&DDNtask_idc                    U(       a$  [         R                  R                  U5      (       d  [        R	                  SU 35        g [        U5      n[        R                  " 5       R                  S5      nU(       a!  UR                   SU SU UR                   3nOUR                   SU UR                   3nU R                  U-  n[        R                  " [        U5      [        U5      5        [        R                  SU 35        U R!                  X0R                  U5        [        U5      $ ! ["         a!  n[        R%                  SU 3SS9   SnAgSnAff = f)	u   
将日志文件移动到失败日志目录

Args:
    log_file: 原始日志文件路径
    task_id: 任务ID（可选，用于命名）
    
Returns:
    新的日志文件路径，如果移动失败则返回None
r   Nz%Y%m%d_%H%M%S_u&   已移动日志文件到失败目录: u)   移动日志文件到失败目录失败: Tr   )r   r    r!   r"   r#   r   r   nowstrftimestemsuffixr   r%   r&   r'   r(   r)   r*   r+   )r   r   r3   r,   	timestampnew_namer/   r0   s           r   move_log_to_failedLogManager.move_log_to_failedE   s#    rww~~h77NN4XJ?@	H~H !//@I&mm_AgYa	{8??BST&mm_Ai[8IJ..9LKKHs<'89KK@OP ##H.A.A8L|$$ 	LLDQCHSWLX	s   C*D1 1
E;EEr,   
target_dirr;   c                     UR                   nUR                  nUR                  nU SU 3U S3U S3/nU H  nXH-  n	U	R                  5       (       d  M  U	R	                  5       (       d  M5   U(       aK  [        U5      R                  n
[        U5      R                  nSU;   a  U
 SU 3nOSU;   a  U
 S3nOUnX,-  nOX(-  n[        R                  " [        U	5      [        U5      5        [        R                  SU	R                   SUR                   35        M     g! [         a1  n[        R                  SU	R                   SU 35         SnAGM  SnAff = f! [         a"  n[        R                  S	U 35         SnAgSnAff = f)
u   
移动相关的日志文件（如_readable.txt等）

Args:
    log_path: 原始日志文件路径
    target_dir: 目标目录
    new_name: 新文件名（可选，如果不提供则使用原文件名）
	_readablez_readable.txtz	.readableu   已移动相关日志文件: z -> u   移动相关日志文件失败 : Nu#   查找相关日志文件时出错: )parentr8   r9   r!   is_filer   r%   r&   r'   r"   debugr$   r*   r#   )r   r,   r>   r;   log_dirlog_stem
log_suffixpatternspatternrelated_filenew_stem
new_suffixnew_related_nametarget_filer0   s                  r   r)   LogManager._move_related_logsl   s   (	FooG}}H!J *Ij\2*M**I&H $&0&&((\-A-A-C-Cc# (,H~':':H)-h)>)>J*g56>Zy3U 0!,!76>Zy3I 03; 0*4*GK*4*>KC$5s;7GH'D\EVEVDWW[\g\l\l[m%no- $. % c)HIZIZH[[]^_]`'abbc  	FNN@DEE	FsI   AE E .B.D!E !
E+%EE EE 
F)FFdaysc                    U R                   R                  5       (       d  gSn[        R                  " 5       R	                  5       US-  S-  -
  n U R                   R                  S5       Hr  nUR                  5       (       d  M   UR                  5       R                  U:  a9  UR                  5         US-  n[        R                  SUR                   35        Mr  Mt     US:  a  [        R!                  SU SU S35        U$ ! [         a0  n[        R                  SUR                   SU 35         S	nAM  S	nAff = f! [         a!  n[        R                  S
U 3SS9   S	nANS	nAff = f)ut   
清理旧的失败日志文件

Args:
    days: 保留天数，默认30天
    
Returns:
    清理的文件数量
r      i  *   u   已删除旧失败日志: u   删除旧失败日志失败 rA   Nu    清理旧失败日志时出错: Tr   u
   已清理 u"    个旧失败日志文件（超过u   天）)r   r!   r   r6   r:   globrC   statst_mtimeunlinkr"   rD   r$   r*   r#   r+   r(   )r   rP   deleted_countcutoff_timer   r0   s         r   cleanup_old_failed_logs"LogManager.cleanup_old_failed_logs   sQ    ""))++lln..0D2I4DE	P //44S9##%%\#==?33kA$OO-)Q.M"LL+Ehmm_)UV B : 1KK*]O3UVZU[[abc % \)Ehmm_TVWXVY'Z[[\  	PLL;A3?$LO	PsC   1E ADE 
D?%D:4E :D??E 
E-E((E-c                     [        U5      nUS-  nUR                  5       (       d  / $ / nUR                  S5       H4  nUR                  5       (       d  M  UR	                  [        U5      5        M6     [        U5      $ )u   
获取题目目录下的所有日志文件

Args:
    challenge_output_dir: 题目输出目录
    
Returns:
    日志文件路径列表
r   rS   )r   r!   rU   rC   appendr'   sorted)r   r   r-   rE   	log_filesr   s         r   get_log_files_in_challenge%LogManager.get_log_files_in_challenge   sq     12&(~~I	S)H!!  X/ * i  r   )r
   r   )r   )N)   )__name__
__module____qualname____firstlineno____doc__r'   r   r   r1   r<   r   r)   intr[   r   ra   __static_attributes__ r   r   r   r      s    	?S 	?$c $ $QYZ]Q^ $L%3 %# %RZ[^R_ %N1F4 1FT 1FXVY] 1Ff!C ! !F!s !tCy !r   r   )rh   r   r%   loggingpathlibr   typingr   r   r   	getLoggerrd   r"   r   rk   r   r   <module>rp      s:   
 
    ! 			8	$F! F!r   