Log Trigger?

Is there a way to trigger a macro by monitoring a log file?

Specifically, I want to continuously check for new occurrences of a matching string in a log and then either run a macro or an Execute Shell that can call a macro.

I've seen this thread but it seems like the links presented there are more for monitoring processes whereas I'm interested in monitoring log files.

Hey Greg,

Can Keyboard Maestro do it?

Nyet...

Can it be done using Keyboard Maestro?

Likely...

This one runs as a job in the Terminal, and I'd probably prefer that to a KM Execute a Shell Script action.

A few more nuggets of information:

-Chris

1 Like

Please describe me what you are trying to achieve with more details, so I can help you.

1 Like

Local or remote log file? Either way, as @ccstone suggests this would be better done using command line tools -- but you could then call KM macro(s) as required.

For a local file, something like

tail -fn0 /path/to/logfile.txt | awk '/A bad thing happened/ { print "open kmtrigger://macro=MacroToRun" }

(you could instead trigger the macro using AppleScript via osascript).

You could fire that up in Terminal as and when you needed monitoring. If you want to monitor all the time -- or, more probably, all the time that you are logged in so KM can do it's thing -- you could set up a LaunchAgent to start the script off at login. There's a good launchd tutorial at https://www.launchd.info that'll help with that.

1 Like

Here's what it's supposed to be doing on one of my local machines:

  1. KM Engine launched on user login
  2. Macro triggered on KM Engine launch
  3. Macro starts application
  4. Macro opens something in the application at random
  5. Macro waits 5 minutes
  6. Macro repeats 4-5 indefinitely, until another macro restarts the machine during off hours

The issue is that sometimes it opens something that causes a "soft crash" (step 4) and I have exhausted efforts to prevent it. What I mean by "soft crash" is that the app is still technically running so I can't simply check to see if it is no longer running.

It does, however, print a log message when this error occurs.

My plan is to monitor for the log message and then trigger a macro that will force quit the application and restart the macro normally controlling it.

I am remembering launchd now and will add that in to my solution - thank you!

Is that happening as a result of step 4? I'd seriously consider putting my check/restart in as part of that macro, perhaps (pseudocode):

repeat
    do thing to dodgyApp
    pause 2 seconds #or however long it takes for the error to hit the log)
    set Local__appCrashed to (grep log for error)
    if Local__appCrashed is true
        restart dodgyApp
        pause until dodgyApp is running
    endIf
until Local__appCrashed is false

If nothing else it keeps the relevant code all in the same place -- useful when you come back to it in a year's time trying to work out why dodgyApp keeps restarting behind your back, or you migrate to another machine and your LaunchAgent doesn't make it over!

Good point. Perhaps I'll revisit my efforts to monitor inside the macro. I was trying to do this before by pausing for an error message image. The macro wasn't catching it for whatever reason.

I didn't think to continuously check the log file in the macro instead of the image. Probably because I knew there were likely better tools to do it.

Checking inside the macro also means I'll have to break up the "wait for 5 minutes" part into a loop that does two things 150 times:

  1. Calls the log check
  2. Pauses for 2 seconds

I think I was trying to avoid this because I want to add even more waits depending on what is being opened in the application. I just wanted to have a simple switch on content type regarding time to pause, but it seems like adding just a little more complexity here would be better than introducing external dependencies.

Like you said - it's better to have everything in one place!

Thanks for the pseudocode!

I'd try and avoid that too!

Your workflow above implies you send one command to dodgyApp every 5 minutes, which will either succeed or require dodgyApp to be restarted (possibly repeating the try/restart until success, which is what my pseudocode does). If you need to do that more than 3 or 4 times per round then dodgyApp really is dodgy and you need to reconsider.

If, instead, your "macro runs every 5 minutes" is creating a situation where dodgyApp is repeatedly called over that period or dodgyApp could crash at any time as a result of a single call but at a time unrelated to when the call was made -- I'd go back to the "LaunchAgent checking the log file" plan. IMO it'll be less costly to spawn one background task at login and leave it running than to have KM spawn (then destroy) a new shell process every 2 seconds throughout the day.

But it really does depend on what dodgyApp is and what you are trying to do with it. If it's locking up as often as you say then I can't help but think there's a better way to do things...