-- ~/.hammerspoon/ArqMonitor.lua local arqMenu = hs.menubar.new() local logPath = "/Library/Application Support/ArqAgent/logs/" local targets = { { label = "Arq Storage", search = "Arq Cloud Storage" }, { label = "Google Drive", search = "Google Drive" } } local function getDestinationStatus() local menuTable = {} for _, target in ipairs(targets) do -- Find the latest log file that contains the target name local findLog = "grep -l '" .. target.search .. "' '" .. logPath .. "'*.log 2>/dev/null | xargs ls -t | head -n 1" local logFile = hs.execute(findLog) local status = "⏳ Waiting" if logFile and logFile ~= "" then logFile = logFile:gsub("%s+$", "") -- Check for the 'ended' string in that specific file local checkEnded = "grep 'Backup activity ended' '" .. logFile .. "'" local finished = hs.execute(checkEnded) if finished and finished ~= "" then status = "✅ Completed" else -- If not ended, check if it at least started or is snapshotting local checkStarted = "grep -E 'Backup activity started|snapshot' '" .. logFile .. "'" local started = hs.execute(checkStarted) if started and started ~= "" then status = "⏳ In Progress" end end end table.insert(menuTable, { title = target.label .. ": " .. status, disabled = true }) end table.insert(menuTable, { title = "-" }) table.insert(menuTable, { title = "Force Refresh", fn = function() updateArqStatus() end }) return menuTable end function updateArqStatus() -- Global status: check the absolute newest log file in the folder local lastLogCmd = "ls -t '" .. logPath .. "'*.log 2>/dev/null | head -n 1" local lastLog = hs.execute(lastLogCmd) if lastLog and lastLog ~= "" then lastLog = lastLog:gsub("%s+$", "") local finished = hs.execute("grep 'Backup activity ended' '" .. lastLog .. "'") if finished and finished ~= "" then arqMenu:setTitle("Arq: ✅") else arqMenu:setTitle("Arq: ⏳") end else arqMenu:setTitle("Arq: ❓") end arqMenu:setMenu(getDestinationStatus) end -- Refresh every 5 minutes local arqTimer = hs.timer.doEvery(300, updateArqStatus) updateArqStatus() return arqMenu