Shell 脚本不断检查文本文件中的日志数据,然后运行程序

发布于 2024-12-07 07:24:11 字数 320 浏览 0 评论 0原文

我有一个 java 程序,由于记录在 .log 文件中的错误而经常停止。什么可以是一个简单的 shell 脚本来检测最后/最新行中的特定文本

[INFO] Stream closed

,然后运行以下命令

java -jar xyz.jar

这应该永远持续发生(可能每两分钟左右一次),因为 xyz.jar 写入日志文件。

文本stream closeed 可能会多次出现在日志文件中。我只是希望它在最后一行出现时采取行动。

I have a java program that stops often due to errors which is logged in a .log file. What can be a simple shell script to detect a particular text in the last/latest line say

[INFO] Stream closed

and then run the following command

java -jar xyz.jar

This should keep on happening forever(possibly after every two minutes or so) because xyz.jar writes the log file.

The text stream closed can arrive a lot of times in the log file. I just want it to take an action when it comes in the last line.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

草莓味的萝莉 2024-12-14 07:24:11

怎么样

while [[ true ]];
do
  sleep 120
  tail -1 logfile | grep -q "[INFO] Stream Closed"
  if [[ $? -eq 1 ]]
  then
    java -jar xyz.jar &
  fi
done

How about

while [[ true ]];
do
  sleep 120
  tail -1 logfile | grep -q "[INFO] Stream Closed"
  if [[ $? -eq 1 ]]
  then
    java -jar xyz.jar &
  fi
done
故人爱我别走 2024-12-14 07:24:11

可能存在尾部最后日志“Stream Closed”不是真正的最后日志并且进程仍在记录消息的情况。我们可以通过检查进程是否存活来避免这种情况。如果进程退出并且最后一个日志是“Stream Closed”,那么我们需要重新启动应用程序。

#!/bin/bash

java -jar xyz.jar &
PID=$1

while [ true ]
do
   tail -1 logfile | grep -q "Stream Closed" && kill -0 $PID && sleep 20 && continue
   java -jar xyz.jar &
   PID=$1
done

There may be condition where the tailed last log "Stream Closed" is not the real last log and the process is still logging the messages. We can avoid this condition by checking if the process is alive or not. If the process exited and the last log is "Stream Closed" then we need to restart the application.

#!/bin/bash

java -jar xyz.jar &
PID=$1

while [ true ]
do
   tail -1 logfile | grep -q "Stream Closed" && kill -0 $PID && sleep 20 && continue
   java -jar xyz.jar &
   PID=$1
done
星軌x 2024-12-14 07:24:11

我更愿意检查相应的进程是否仍在运行,并在该事件发生时重新启动程序。可能还有其他错误导致进程停止。您可以使用 cronjob 定期(例如每分钟)执行此类检查。

另外,您可能希望改进您​​的 java 代码,以便它不会经常崩溃(如果您有权访问该代码)。

I would prefer checking whether the corresponding process is still running and restart the program on that event. There might be other errors that cause the process to stop. You can use a cronjob to periodically (like every minute) perform such a check.

Also, you might want to improve your java code so that it does not crash that often (if you have access to the code).

凌乱心跳 2024-12-14 07:24:11

我使用看门狗脚本解决了这个问题,该脚本直接检查(grep)程序是否正在运行。通过每分钟调用一次看门狗(来自ubuntu下的cron),我基本上保证(程序和环境非常稳定)没有程序离线时间超过59秒。

该脚本将使用数组中的名称检查程序列表,并查看每个程序是否正在运行,如果没有,则启动它。

#!/bin/bash
#
# watchdog
#
# Run as a cron job to keep an eye on what_to_monitor which should always
# be running. Restart what_to_monitor and send notification as needed.
#
# This needs to be run as root or a user that can start system services.
#
# Revisions: 0.1 (20100506), 0.2 (20100507)

# first prog to check
NAME[0]=soc_gt2
# 2nd
NAME[1]=soc_gt0
# 3rd, etc etc
NAME[2]=soc_gp00


# START=/usr/sbin/$NAME
[email protected]
[email protected]
GREP=/bin/grep
PS=/bin/ps
NOP=/bin/true
DATE=/bin/date
MAIL=/bin/mail
RM=/bin/rm


for nameTemp in "${NAME[@]}"; do
    $PS -ef|$GREP -v grep|$GREP $nameTemp >/dev/null 2>&1
    case "$?" in
    0)
        # It is running in this case so we do nothing.
        echo "$nameTemp is RUNNING OK. Relax."

        $NOP
        ;;
    1)
        echo "$nameTemp is NOT RUNNING. Starting $nameTemp and sending notices."
        START=/usr/sbin/$nameTemp 
        $START 2>&1 >/dev/null &
        NOTICE=/tmp/watchdog.txt
        echo "$NAME was not running and was started on `$DATE`" > $NOTICE
        # $MAIL -n -s "watchdog notice" -c $NOTIFYCC $NOTIFY < $NOTICE
        $RM -f $NOTICE
        ;;
    esac
done

exit

我不使用日志验证,尽管您可以轻松地将其合并到您自己的版本中(例如,只需更改 grep 进行日志检查)。

如果您从命令行(或腻子,如果您是远程连接)运行它,您将看到哪些工作正常,哪些无效。已经使用它几个月了,没有出现任何问题。每当你想查看什么在工作时就调用它(无论它是否在 cron 下运行)。

您还可以将所有关键程序放在一个文件夹中,列出目录并检查该文件夹中的每个文件是否都有一个以相同名称运行的程序。或者逐行读取 txt 文件,每一行都对应于应该运行的程序。等等等等

i solved this using a watchdog script that checks directly (grep) if program(s) is(are) running. by calling watchdog every minute (from cron under ubuntu), i basically guarantee (programs and environment are VERY stable) that no program will stay offline for more than 59 seconds.

this script will check a list of programs using the name in an array and see if each one is running, and, in case not, start it.

#!/bin/bash
#
# watchdog
#
# Run as a cron job to keep an eye on what_to_monitor which should always
# be running. Restart what_to_monitor and send notification as needed.
#
# This needs to be run as root or a user that can start system services.
#
# Revisions: 0.1 (20100506), 0.2 (20100507)

# first prog to check
NAME[0]=soc_gt2
# 2nd
NAME[1]=soc_gt0
# 3rd, etc etc
NAME[2]=soc_gp00


# START=/usr/sbin/$NAME
[email protected]
[email protected]
GREP=/bin/grep
PS=/bin/ps
NOP=/bin/true
DATE=/bin/date
MAIL=/bin/mail
RM=/bin/rm


for nameTemp in "${NAME[@]}"; do
    $PS -ef|$GREP -v grep|$GREP $nameTemp >/dev/null 2>&1
    case "$?" in
    0)
        # It is running in this case so we do nothing.
        echo "$nameTemp is RUNNING OK. Relax."

        $NOP
        ;;
    1)
        echo "$nameTemp is NOT RUNNING. Starting $nameTemp and sending notices."
        START=/usr/sbin/$nameTemp 
        $START 2>&1 >/dev/null &
        NOTICE=/tmp/watchdog.txt
        echo "$NAME was not running and was started on `$DATE`" > $NOTICE
        # $MAIL -n -s "watchdog notice" -c $NOTIFYCC $NOTIFY < $NOTICE
        $RM -f $NOTICE
        ;;
    esac
done

exit

i do not use the log verification, though you could easily incorporate that into your own version (just change grep for log check, for example).

if you run it from command line (or putty, if you are remotely connected), you will see what was working and what wasnt. have been using it for months now without a hiccup. just call it whenever you want to see what's working (regardless of it running under cron).

you could also place all your critical programs in one folder, do a directory list and check if every file in that folder has a program running under the same name. or read a txt file line by line, with every line correspoding to a program that is supposed to be running. etcetcetc

翻身的咸鱼 2024-12-14 07:24:11

一个好方法是使用 awk 命令:

tail -f somelog.log | awk '/.*[INFO] Stream Closed.*/ { system("java -jar xyz.jar") }'

它会持续监视日志流,当正则表达式匹配时,它会触发您设置的任何系统命令,即您在 shell 中输入的任何命令。

如果你真的想做得很好,你可以将该行放入 .sh 文件中,并从进程监控守护进程(如 upstart)运行该 .sh 文件,以确保它永远不会死掉。

又漂亮又干净=D

A good way is to use the awk command:

tail -f somelog.log | awk '/.*[INFO] Stream Closed.*/ { system("java -jar xyz.jar") }'

This continually monitors the log stream and when the regular expression matches its fires off whatever system command you have set, which is anything you would type into a shell.

If you really wanna be good you can put that line into a .sh file and run that .sh file from a process monitoring daemon like upstart to ensure that it never dies.

Nice and clean =D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文