Class: Pindo::TaskSystem::MultiLineOutputManager
- Inherits:
-
OutputSink
- Object
- OutputSink
- Pindo::TaskSystem::MultiLineOutputManager
- Defined in:
- lib/pindo/module/task/output/multi_line_output_manager.rb
Overview
多行输出管理器管理所有任务的输出(终端显示 + 日志文件)实现 OutputSink 接口
Instance Method Summary collapse
-
#error_task(task_id, error_message) ⇒ Object
任务失败.
-
#initialize(log_dir: './pindo_logs', max_lines_per_task: 5, max_recent_completed: 3, auto_adjust: true) ⇒ MultiLineOutputManager
constructor
初始化输出管理器.
-
#log_detail(task_id, message) ⇒ Object
记录详细日志.
-
#log_error(task_id, message) ⇒ Object
记录错误.
-
#log_info(task_id, message) ⇒ Object
记录日志(更新终端 + 写文件).
-
#log_warning(task_id, message) ⇒ Object
记录警告.
-
#register_task(task) ⇒ Object
注册任务到输出管理器.
-
#start_task(task_id) ⇒ Object
任务开始.
-
#success_task(task_id, message = nil, execution_time: nil) ⇒ Object
任务成功.
-
#update_current_line(task_id, message) ⇒ Object
更新当前行(不滚动).
-
#update_progress(task_id, message) ⇒ Object
更新进度(终端可见 + 日志记录).
Constructor Details
#initialize(log_dir: './pindo_logs', max_lines_per_task: 5, max_recent_completed: 3, auto_adjust: true) ⇒ MultiLineOutputManager
初始化输出管理器
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 17 def initialize( log_dir: './pindo_logs', max_lines_per_task: 5, max_recent_completed: 3, auto_adjust: true ) @mutex = Mutex.new @log_dir = log_dir @max_lines_per_task = max_lines_per_task @max_recent_completed = max_recent_completed @auto_adjust = auto_adjust # 任务显示器映射 @task_displays = {} # task_id => MultiLineTaskDisplay # 日志文件映射 @task_loggers = {} # task_id => File # 终端状态 @terminal_lines = 0 # 当前占用的终端行数 @last_render_time = Time.now @min_render_interval = 0.1 # 最小刷新间隔(秒) # 创建日志目录 FileUtils.mkdir_p(@log_dir) # 隐藏光标(更流畅的动画) STDOUT.print "\e[?25l" if supports_ansi? # 注册退出时恢复光标 at_exit { STDOUT.print "\e[?25h" if supports_ansi? } end |
Instance Method Details
#error_task(task_id, error_message) ⇒ Object
任务失败
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 125 def error_task(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.mark_error() write_log(task_id, "=" * 60) write_log(task_id, "任务失败: #{}") write_log(task_id, "=" * 60) close_log(task_id) render_terminal end end |
#log_detail(task_id, message) ⇒ Object
记录详细日志
211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 211 def log_detail(task_id, ) @mutex.synchronize do # 只有非空消息才更新显示 unless .strip.empty? display = @task_displays[task_id] # 为了避免刷屏,普通日志使用 update_last_line 还是 add_line? # 考虑到 log_detail 可能是一行行输出,使用 add_line 更像滚动的日志 display&.add_line() end write_log(task_id, ) render_terminal end end |
#log_error(task_id, message) ⇒ Object
记录错误
198 199 200 201 202 203 204 205 206 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 198 def log_error(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.add_line("\e[31m#{}\e[0m") # 红色高亮 write_log(task_id, "[ERROR] #{}") render_terminal end end |
#log_info(task_id, message) ⇒ Object
记录日志(更新终端 + 写文件)
172 173 174 175 176 177 178 179 180 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 172 def log_info(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.add_line() write_log(task_id, "[INFO] #{}") render_terminal end end |
#log_warning(task_id, message) ⇒ Object
记录警告
185 186 187 188 189 190 191 192 193 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 185 def log_warning(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.add_line("\e[33m#{}\e[0m") # 黄色高亮 write_log(task_id, "[WARN] #{}") render_terminal end end |
#register_task(task) ⇒ Object
注册任务到输出管理器
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 56 def register_task(task) @mutex.synchronize do task_id = task.id # 创建多行显示器 display = MultiLineTaskDisplay.new( task_id, task.name, max_lines: @max_lines_per_task ) @task_displays[task_id] = display # 创建日志文件 log_file_name = "#{task.task_key}_#{task_id}.log" log_file_path = File.join(@log_dir, log_file_name) @task_loggers[task_id] = File.open(log_file_path, 'w') # 渲染终端 render_terminal end end |
#start_task(task_id) ⇒ Object
任务开始
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 84 def start_task(task_id) @mutex.synchronize do display = @task_displays[task_id] display&.add_line("任务开始") write_log(task_id, "=" * 60) write_log(task_id, "任务开始") write_log(task_id, "=" * 60) render_terminal end end |
#success_task(task_id, message = nil, execution_time: nil) ⇒ Object
任务成功
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 101 def success_task(task_id, = nil, execution_time: nil) @mutex.synchronize do display = @task_displays[task_id] msg = if execution_time ? "#{} (耗时 #{execution_time.round(2)}s)" : "完成 (耗时 #{execution_time.round(2)}s)" else || "完成" end display&.mark_success(msg) write_log(task_id, "=" * 60) write_log(task_id, "任务成功: #{msg}") write_log(task_id, "=" * 60) close_log(task_id) render_terminal end end |
#update_current_line(task_id, message) ⇒ Object
更新当前行(不滚动)
159 160 161 162 163 164 165 166 167 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 159 def update_current_line(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.update_last_line() write_log(task_id, "[UPDATE] #{}") render_terminal end end |
#update_progress(task_id, message) ⇒ Object
更新进度(终端可见 + 日志记录)
146 147 148 149 150 151 152 153 154 |
# File 'lib/pindo/module/task/output/multi_line_output_manager.rb', line 146 def update_progress(task_id, ) @mutex.synchronize do display = @task_displays[task_id] display&.add_line() write_log(task_id, "[PROGRESS] #{}") render_terminal end end |