ddbnl / office365-audit-log-collector

Collect / retrieve Office365, AzureAD and DLP audit logs and output to PRTG, Azure Log Analytics Workspace, SQL, Graylog, Fluentd, and/or file output.
https://ddbnl.github.io/office365-audit-log-collector/
MIT License
105 stars 40 forks source link

Improvement: Run Collector as SingleInstance (Linux) #30

Closed Gill-Bates closed 2 years ago

Gill-Bates commented 2 years ago

I run the collector via cron. I noticed that the collector does not check if an instance is already running before starting. This can cause multiple instances to run in an infinite loop and load the CPU to 100%. I would need to write myself a bash-script for this requirement.

I would find an additional - native - configuration option helpful, like:

collect:
  runAsSingleInstance: True
ddbnl commented 2 years ago

I agree this would be useful. A first step might be to add a 'globalTimeout' parameter, which would force exit the collector after a specified number of minutes. This would go a long way to ensure another process is not running, and would be trivial to implement.

Checking if another process is running would be the next step, as I would have to check how to implement this cleanly cross-platform. Might be trivial with python but I would have to check first.

I'll update this issue when I've had time to look at this further; should be this week.

Thanks for the suggestion.

ddbnl commented 2 years ago

I've added the global timeout parameter, you can download the new Linux executable or Windows executable.

I've checked on adding a runAsSingleInstance parameter but I could find no clean way to do this cross-platform. The 'globalTimeout' parameter should be everything you need however. There is no blocking code in the collector, meaning that as soon as the global timeout is reached the program will forcefully exit. There shouldn't be any way in which it can hang and stay around forever. If you run every hour in CRON for example, consider 'globalTimeout: 59' to exit after 59 minutes if it's still running.

Let me know if this solves your (potential) issue :)

Gill-Bates commented 2 years ago

Wow, thank you! I will give it a try and let you know!

PS: You could solve this improvement with psutil

And then iterate through the list and check if you find a running process

import psutil
# Iterate over all running process
for proc in psutil.process_iter():
    try:
        # Get process name & pid from process object.
        processName = proc.name()
        processID = proc.pid
        print(processName , ' ::: ', processID)
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        pass
ddbnl commented 2 years ago

Closing this for now, assuming that the forced timeout provides the same functionality, as I'm not sure how robust cross-platform process finding/killing will be. If it turns out that the timeout is not enough for whatever reason I'll look at it again :)