Detect When the Load Completes?

Does anyone know if it is possible to detect when the completes the initial load of a log file? It would also be helpful to be able to detect the end of a Action > Reload.

I'm working on an updated version of a macro that opens the Keyboard Maestro Engine.log and uses Edit > Find > Find... to highlight a particular failure or timeout. This sequence often fails if the initial load has not completed.

Would this work for you? Just make sure error detection is turned off on the Read File action.

Basically, this code doesn't "wait", it simply tries to reload until it succeeds.

Hi, @Airy. Thanks so much for the reply.

Yes, it seems that the duration of the actions you suggested might closely correlate with the load, but unless I'm missing the point, isn't it likely that the load would be longer since there is additional overhead associate with the app?

With that said, this would be better than pausing some fixed duration:

  1. Open Engine.log; that opens the
  2. Run your actions, calculating the duration.
  3. Add some proportional fudge factor and Pause for that additional amount of time.
  4. Then proceed with Edit > Find > Find...

Group Action (v11.0.1)

Group.kmactions (7.8 KB)

If I'm missing something more fundamental, please let me know. Again, thanks @Airy.

Well then, if you're worried about that, just insert a "Pause 0.25" before (not after) the Read File action in my macro. It has to be "before" because of what the condition in my macro tests.

My method detects and corrects errors. Your method still required a fudge factor that could fail. And you don't have code in your macro to handle a failure, while my macro does handle errors.

When I write macros, I always work hard to make them detect and fix errors.

Thanks for the follow-up, @Airy.

I understand that your macro tests the Read File action, but my goal is to ensure the is fully loaded. Again, I see the correlation, but one does not guarantee the other, correct?

Yes, for the Read File action.

Me too, I was just mocking up an idea. :grinning:

That would work if I wanted to add a fixed bias, but not a proportional one. I'll experiment with very large log files and see which approach works.

That's a fair point. I have no idea. But until you test my app to see if it ever fails, we won't know. In my general experience, once a file is unlocked by any app that was writing to it, it is considered accurate/available for others to use.

Yes, maybe generally available with menu items, etc., but I’ve definitely seen cases where the Find… fails if attempted too early.

Thanks, again, @Airy. I’ll report back after some testing.

If the Find fails, then couldn't you put it in a failure repeat loop, like I did for the file read?

Unfortunately the does not report an error when a Find... is unsuccessful.

Why not just Execute a Shell Script to read ~/Library/logs/Keyboard\ Maestro/Engine.log into a variable and forego all together?

No waiting.

Or you could just use the Read a File action to load the log into a variable.

Yes, I'm using a shell script to locate the latest failure or timeout. But there's one branch of the macro (Main Dialog, Log button) where I want to open the and use Edit > Find > Find... to highlight that lastest failure or timeout.

@Airy, @mrpasini, @tiffle, thanks for your suggestions. After several failed attempts I finally found a menu combination that occurs only after the log file is fully loaded.

Group.kmactions (12 KB)


It seems like you already know what you're looking for (local_ErrorLine) and you are using Console to show it in the log in context.

Otherwise I don't understand what Console is doing for you. You can grep the search term in the log file to find it instantly without opening Console -- but that won't show you context.

Anyway, glad you worked it out to your satisfaction. I just hate to see anyone have to wait for anything :grin:

Yes! For this particular branch of the macro, context is important.

Also, since the macro is opening Engine.log (versus some subset of the file) in the, new KM logs will be seen in real-time.

As an aside, the next version of the macro will provide several methods to modify Engine.log.

  • delete ⇨ delete Engine.log

  • purge:RegEx ⇨ modify Engine.log, retaining all entries except those that match the RegEx

  • keep:RegEx ⇨ modify Engine.log, retaining all entries that match the RegEx

  • tail:n ⇨ modify Engine.log, retaining only the latest n entries

  • today ⇨ modify Engine.log, retaining only entries since midnight

  • days:n ⇨ modify Engine.log, retaining only the latest n days of entries (e.g., days:2 == since midnight yesterday)

  • time:YYYY-MM-DD [hh:mm[:ss]] ⇨ modify Engine.log, retaining only records since the specified date/time

The above Engine.log maintenance can be completed interactively, or silently by calling the macro from another and suppliing the method information via the Execute a Macro With Parameter.


Hi Jim - I know you've marked this as solved but I've just thought of something else you could try.

I just created a demo macro for another user that loaded a file into Excel and then did some further processing. The macro kept failing because Excel took so long to load the file.

So, I tried use a Pause Until action after the File Open action with the condition set to use %FrontDocumentPath% token like this:


and it worked: the macro waited until Excel had loaded the spreadsheet and then continued. I didn't try any other condition like "matches" or whatever since this worked first time so YMMV.

I'm just throwing this in to the ring in case you hadn't already tried it.


Hi, @tiffle. Thanks so much for your response.

In this case, a more appropriate designation would have been Kludged. :grinning:

Very cool! You've gotta love these Keyboard Maestro Version 11 enhancements! :partying_face:

Unfortunately, MMDV; the returns %FrontDocumentPath% almost immediately upon opening, well before the Engine.log is loaded. :sleepy:

So, for now, I'll need to stick with my kludge. (Actually it's a bit uglier than the actions I shared above. I've since discovered that I needed a provision if the current macOS display resolution is low. The @&#$?&! doesn't display the Search field if the window width drops below a threshold; thus the menu enabled/disabled differs. So now, the macro checks the screen resolution and if it's low, maximizes the window during the necessary actions, and then reduces the window to the left half of the display. Crazy, right?)

@tiffle, I'm sure glad you did. I suspect that this approach will come in handy when developing future macros.

Does anyone else find it ironic that a simple approach works for Excel but not for the native macOS Console app? Has the world spun off its axis? :scream:


There’s only one response to the hoops you’ve been jumping through: Gordon Bennett

Definitely - especially after you see the breadth of AppleScript support baked into Excel!

1 Like