lnav icon indicating copy to clipboard operation
lnav copied to clipboard

Execute command when log event matches a pattern

Open sbhal opened this issue 1 year ago • 6 comments

I want to use the lnav Events interface to search for regex in live log files and run a command when a match is found. Do you have any suggestions on how to do this?

Eventually, I want to search log files for when a long-running process finishes, and I want to be notified when it's done.

I also couldn't find a way to execute non-SQL commands when a log event occurs.

sbhal avatar Sep 25 '24 02:09 sbhal

Have you looked into shell_exec? https://docs.lnav.org/en/latest/sqlext.html#shell-exec-cmd-input-options

FaffeF avatar Sep 25 '24 22:09 FaffeF

I also couldn't find a way to execute non-SQL commands when a log event occurs.

Are you trying to execute an lnav command or a shell program? Most of lnav's functionality can be accessed through SQL vtables.

tstack avatar Sep 26 '24 21:09 tstack

I am trying to execute a shell command once log body matches a regex pattern.

I added a watch expression:

:config /log/watch-expressions/testfinished/expr regexp(:log_body, '.*Test run finished .*')

But I am noticing, there are no entries in lnav_events table using

;select * from lnav_events

I also have init sql

CREATE TRIGGER IF NOT EXISTS add_integ_tests_log_events
  AFTER INSERT ON lnav_events WHEN
    -- Check the event type
    jget(NEW.content, '/$schema') =
      'https://lnav.org/event-log-msg-detected-v1.schema.json' AND
    -- Only create the filter when a given format is seen
    jget(NEW.content, '/watch-name') = 'testfinished'
BEGIN
SELECT shell_exec('notify "test finished!"');
END;

sbhal avatar Sep 29 '24 17:09 sbhal

I am trying to execute a shell command once log body matches a regex pattern.

I added a watch expression:

:config /log/watch-expressions/testfinished/expr regexp(:log_body, '.*Test run finished .*')

I think you have the arguments to regexp() flipped around. The regular expression should come first.

tstack avatar Oct 03 '24 20:10 tstack

I get following error while trying to exec "shell_exec"

2025-01-28T15:31:30.453+00:00 E t0 sql_util.cc:552 (1) unsafe use of shell_exec() in "
INSERT INTO lnav_events (content) VALUES (?)
"
2025-01-28T15:31:30.453+00:00 E t0 lnav.events.cc:164 unable to prepare event statement: unable to prepare SQL statement: unsafe use of shell_exec()
2025-01-28T15:31:30.453+00:00 E t0 sql_util.cc:552 (1) unsafe use of shell_exec() in "
INSERT INTO lnav_events (content) VALUES (?)
"
2025-01-28T15:31:30.453+00:00 E t0 lnav.events.cc:164 unable to prepare event statement: unable to prepare SQL statement: unsafe use of shell_exec()

sbhal avatar Jan 28 '25 15:01 sbhal

I get following error while trying to exec "shell_exec"

2025-01-28T15:31:30.453+00:00 E t0 sql_util.cc:552 (1) unsafe use of shell_exec() in "
INSERT INTO lnav_events (content) VALUES (?)
"

Ah, sorry, I forgot I had marked shell_exec() as only usable from top-level SQL and not within a TRIGGER. That's probably the right thing to do. That's probably the right thing to do though. So, we'll need to figure out another approach.

One option would be to ATTACH a SQLite DB on disk inside of lnav. You can then write your trigger to do an INSERT into a table in that DB. A separate process could poll the on-disk DB for changes and execute the commands as they come in.

tstack avatar Jan 30 '25 22:01 tstack