@@ -33,21 +33,24 @@ async def submit_canfar_job():
3333 this will depend on the type of CANFAR job that we were running though.
3434
3535"""
36-
37-
3836from __future__ import annotations
37+ import os
38+ import pprint
3939
40+ from canfar .sessions import Session
4041from dataclasses import dataclass
4142
42- from prefect import task
43+ from prefect import task , flow
4344from prefect .client .orchestration import get_client
4445from prefect .server .schemas .filters import FlowRunFilter , FlowRunFilterState
4546from prefect .server .schemas .states import StateType
4647from prefect .states import Failed
4748
4849from print_all_open_sessions import get_open_sessions
50+ from vos import Client
4951
5052TAG_PREFIX = "canfar_session:"
53+ VOS_LOG_FOLDER = "arc:projects/CIRADA/polarimetry/ASKAP/Pipeline_logs/canfar_logs"
5154
5255
5356@dataclass (frozen = True )
@@ -206,3 +209,85 @@ async def reconcile_running_prefect_with_canfar_task(limit: int = 200) -> dict:
206209 "skipped_untagged" : result .skipped_untagged ,
207210 }
208211
212+ @flow (name = "Get completed sessions logs and push to Canfar directory" )
213+ def get_completed_session_logs ():
214+ """
215+ Get recently completed CANFAR sessions and push their logs to Canfar directory.
216+ This includes Succeeded, Completed, Failed or Error sessions.
217+ The directory is /arc/projects/CIRADA/polarimetry/ASKAP/Pipeline_logs/canfar_logs.
218+ """
219+ session = Session ()
220+ statuses = ["Succeeded" , "Completed" , "Failed" , "Error" ]
221+ # Get all session ids of completed sessions
222+ all_session_ids = [
223+ s ["id" ]
224+ for status in statuses
225+ for s in (session .fetch (kind = "headless" , status = status ) or [])
226+ ]
227+ for session_id in all_session_ids :
228+ # Get logs for each session
229+ get_logs (session , session_id )
230+
231+ def push_logs_to_canfar (tmp_file ):
232+ """
233+ Copy Canfar session logs to Canfar directory and remove local file
234+ Args:
235+ tmp_file: Local log file to copy and delete
236+ """
237+ client = Client ()
238+
239+ # Ensure remote directory exists
240+ try :
241+ client .mkdir (VOS_LOG_FOLDER )
242+ except :
243+ pass # Directory might already exist
244+
245+ try :
246+ remote_file = f"{ VOS_LOG_FOLDER } /{ tmp_file } "
247+ client .copy (tmp_file , remote_file )
248+ print (f"Upload Canfar log to { remote_file } completed successfully!\n " )
249+ except Exception as e :
250+ print (f"Failed to upload { tmp_file } to Canfar: { e } \n " )
251+ return
252+
253+ # Clean up local file
254+ os .remove (tmp_file )
255+
256+ def log_exists_in_canfar_dir (session_id ):
257+ """
258+ Check if log already exists in Canfar directory.
259+ Args:
260+ session_id: ID of the session
261+ Returns:
262+ True if log exists, False otherwise
263+ """
264+ client = Client ()
265+ file_name = f"{ VOS_LOG_FOLDER } /{ session_id } .log"
266+ try :
267+ return client .isfile (file_name )
268+ except :
269+ # Folder doesn't exist yet
270+ return False
271+
272+
273+ def get_logs (session , session_id ):
274+ """
275+ Get logs for a Canfar session.
276+
277+ Args:
278+ session: Canfar session object
279+ session_id: ID of the session to monitor
280+ output_file: File to write logs to
281+ """
282+ if log_exists_in_canfar_dir (session_id ):
283+ return
284+
285+ tmp_file = f"{ session_id } .log"
286+
287+ with open (tmp_file , "w" ) as f :
288+ # Fetch logs before exiting
289+ logs_dict = session .logs (session_id ).get (session_id )
290+ f .write (pprint .pformat (logs_dict , depth = 4 ))
291+ f .flush
292+ push_logs_to_canfar (tmp_file )
293+
0 commit comments