python - Logging 到文件中,并为每个命令 bash 脚本添加时间戳

我正在编写一个与多个模块集成并调用多个脚本(python、js 等)的 bash 脚本。我想将所有内容(从 bash,从 python/js 脚本)记录到一个日志文件中,并为其添加时间戳。

因此,假设我的 Bash 脚本称为 bash-script.sh,我的 Python 脚本称为 python-script.py,而我的 js 脚本是 js-script.js。日志文件是 out.log

现在,我将把这个问题一分为二。

第一部分:

要记录 bash 脚本中的每个命令并为其添加时间戳,bash-script.sh 以以下内容开头:

#!/bin/bash
source ~/.bashrc

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1> out.log 2>&1
exec > >(while IFS= read -r line; do printf '%s %s %s\n' "$(date --rfc-3339=seconds)" "[Bash-script]" "$line"; done 3>out.log)

问题是,脚本正在为所有内容添加时间戳,包括换行符。此外,由于我正在调用外部脚本,它添加了一些符号,使整个事情变得超级丑陋。这是一个输出示例:

022-05-18 16:37:01+00:00 [Bash-script] Bash script started!
2022-05-18 16:37:01+00:00 [Bash-script] Stopping all services
2022-05-18 16:37:02+00:00 [Bash-script] ● srv1.service - Service1 
2022-05-18 16:37:02+00:00 [Bash-script]   Drop-In: /etc/systemd/system/
2022-05-18 16:37:06+00:00 [Bash-script]
2022-05-18 16:37:06,232 [MainThread] INFO [python-script] In python-script.py

我想摆脱换行符和符号(●)

此外,我有一个函数 WaitForServices 在启动服务列表后运行,它基本上等待(通过休眠 x 秒数)直到所有服务完全启动。在那之前,它会一直打印 waiting for services x

out.log 文件中的日志条目这些“等待”打印只是回显,没有时间戳。输出示例:

*我什至不确定完成的 3>out.log 是否有意义,如果有错误请纠正我。

第二部分

由于我想与 python 和 js 等其他脚本集成,并写入同一日志,因此我使用 >> 重定向输出,我不确定这是一个好习惯。如果 python 或 js 脚本返回错误(差异大于 0 的退出代码),我还希望 bash 脚本完全退出。这就是我目前的做法:

bash-script.sh:

#!/bin/bash
source ~/.bashrc
    
    exec 3>&1 4>&2
    trap 'exec 2>&4 1>&3' 0 1 2 3
    exec 1> out.log 2>&1
    exec > >(while IFS= read -r line; do printf '%s %s %s\n' "$(date --rfc-3339=seconds)" "[Bash-script]" "$line"; done 3>out.log)

function exitCode {
  if [ "$?" != "0" ];then
      echo Exiting...
      exit;
  fi
}

.....code
.....code

PYTHONPATH=.. /path-to-virtual-env/python python-script.py  >> out.log ; exitCode $?

.....more code

sudo node /path-to-js-file/js-script.js  >> out.log ; exitCode $?

.....more code

现在,我很确定这很愚蠢,但我找不到任何其他方法来实现它。我在 python 脚本中使用 logging 库,但是当我指定 filename=out.log (在同一个目录中)时,什么都没有发生。

logging.basicConfig(filename='out.log',format="%(asctime)s %(levelname)s [%(module)s] %(message)s", level=logging.INFO, force=True)

非常感谢您的帮助

回答1

我不确定这是否可行,但如果你有另一个 bash 脚本,它运行第一个 bash 脚本并将输出通过管道传输到类似 https://github.com/zmwangx/ets 的东西,它会自动时间戳每一行。

/path/to/bash-script.sh 2>&1 | ets -f "[%F %T] [bash-script]"
/path/to/python-script.py 2>&1 | ets -f "[%F %T] [python-script]"
/path/to/js-script.js 2>&1 | ets -f "[%F %T] [js-script]"

你正在走的当前道路非常混乱和复杂。这显然不会摆脱空行等。我在想,你需要一个单独的脚本来稍后解析它。

相似文章