From 8ea63b468c7c2a2a8ac382efc41660242d80fe43 Mon Sep 17 00:00:00 2001 From: nopiadintya <61934935+nopiadintya@users.noreply.github.com> Date: Thu, 29 Jan 2026 20:13:58 +0700 Subject: [PATCH 1/2] Add files via upload --- scripts/artifacts/droneFlightLog.py | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 scripts/artifacts/droneFlightLog.py diff --git a/scripts/artifacts/droneFlightLog.py b/scripts/artifacts/droneFlightLog.py new file mode 100644 index 00000000..5e895fda --- /dev/null +++ b/scripts/artifacts/droneFlightLog.py @@ -0,0 +1,66 @@ +__artifacts_v2__ = { + "droneFlightLog": { + "name": "Drone - .LOG files", + "description": "Parse log data from DJI Drone LOG files (*.LOG) and Extracts Events.", + "author": "@NoviAdintya, @HudanStudiawan, @BaskoroAdiPratomo", + "version": "1.1", + "date": "2025-03-16", + "requirements": "DJI drone log files (*.log) from device storage.", + "category": "Drone Logs", + "notes": "Processes log timestamps, log levels, sources, and messages.", + "paths": ("**/*.log",), + "output_types": "all", + "artifact_icon": "slack" + } +} + +import re +import os +import datetime +from scripts.ilapfuncs import artifact_processor, logfunc + +@artifact_processor +def droneFlightLog(files_found, report_folder, seeker, wrap_text, timezone_offset): + data_list = [] + source_paths = set() + + sorted_files = sorted(files_found, key=lambda x: os.path.getmtime(x)) + logfunc(f'Found {len(sorted_files)} log files.') + + for file_found in sorted_files: + if file_found.lower().endswith('.log'): + logfunc(f'Processing: {file_found}') + log_entries = parse_dji_log(file_found) + if log_entries: + data_list.extend(log_entries) + source_paths.add(file_found) + + if not data_list: + logfunc('No valid log data found in any file.') + return None + + data_headers = (('Timestamp', 'datetime'), 'Log Level', 'Source', 'Message') + return data_headers, data_list, ', '.join(source_paths) + +def parse_dji_log(file_path): + log_entries = [] + try: + file_date = datetime.datetime.fromtimestamp(os.path.getmtime(file_path)).date() + + with open(file_path, 'r', errors='ignore') as file: + for line in file: + match = re.search(r'(\d{2}:\d{2}:\d{2}\.\d{3})\s*\[(.)\]\s*\[(.*?)\]\s*(.+)', line) + if match: + time_part, log_level, log_source, message = match.groups() + timestamp = f"{file_date} {time_part}" + + # Hapus prefix seperti ":[com.dji.common]" + message = re.sub(r':\[\w+\.\w+\.\w+\]\s*', '', message).strip() + + log_entries.append((timestamp, log_level, log_source, message)) + except Exception as e: + logfunc(f"Error processing {file_path}: {str(e)}") + + return log_entries + + From f7d3090c2f8359264c40d74fa1c54b41480e0454 Mon Sep 17 00:00:00 2001 From: nopiadintya <61934935+nopiadintya@users.noreply.github.com> Date: Thu, 29 Jan 2026 20:23:05 +0700 Subject: [PATCH 2/2] Update droneFlightLog.py --- scripts/artifacts/droneFlightLog.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/scripts/artifacts/droneFlightLog.py b/scripts/artifacts/droneFlightLog.py index 5e895fda..5825d30c 100644 --- a/scripts/artifacts/droneFlightLog.py +++ b/scripts/artifacts/droneFlightLog.py @@ -20,13 +20,11 @@ from scripts.ilapfuncs import artifact_processor, logfunc @artifact_processor -def droneFlightLog(files_found, report_folder, seeker, wrap_text, timezone_offset): +def droneFlightLog(files_found, _report_folder, _seeker, _wrap_text, _timezone_offset): data_list = [] source_paths = set() - - sorted_files = sorted(files_found, key=lambda x: os.path.getmtime(x)) + sorted_files = sorted(files_found, key=os.path.getmtime) logfunc(f'Found {len(sorted_files)} log files.') - for file_found in sorted_files: if file_found.lower().endswith('.log'): logfunc(f'Processing: {file_found}') @@ -34,11 +32,9 @@ def droneFlightLog(files_found, report_folder, seeker, wrap_text, timezone_offse if log_entries: data_list.extend(log_entries) source_paths.add(file_found) - if not data_list: logfunc('No valid log data found in any file.') return None - data_headers = (('Timestamp', 'datetime'), 'Log Level', 'Source', 'Message') return data_headers, data_list, ', '.join(source_paths) @@ -46,21 +42,14 @@ def parse_dji_log(file_path): log_entries = [] try: file_date = datetime.datetime.fromtimestamp(os.path.getmtime(file_path)).date() - - with open(file_path, 'r', errors='ignore') as file: + with open(file_path, 'r', encoding='utf-8', errors='ignore') as file: for line in file: match = re.search(r'(\d{2}:\d{2}:\d{2}\.\d{3})\s*\[(.)\]\s*\[(.*?)\]\s*(.+)', line) if match: time_part, log_level, log_source, message = match.groups() timestamp = f"{file_date} {time_part}" - - # Hapus prefix seperti ":[com.dji.common]" message = re.sub(r':\[\w+\.\w+\.\w+\]\s*', '', message).strip() - log_entries.append((timestamp, log_level, log_source, message)) - except Exception as e: + except (OSError, RuntimeError) as e: logfunc(f"Error processing {file_path}: {str(e)}") - return log_entries - -