通过Promtail、Loki和Grafana记录Bash历史

789 阅读5分钟

[

Mykola Prokopenko

](medium.com/@mykprok?so…)

米科拉-普罗科佩科

关注

6月21日

-

8分钟阅读

[

保存

](medium.com/m/signin?ac…)

通过Promtail、Loki和Grafana记录Bash历史

我们经常使用bash控制台。有时你必须记住谁做了什么,什么时候运行了什么命令,一般来说要观察基础设施中的用户。或者,你怎么能轻易得到你使用apt upgrade并升级例如Nginx的时间和日期?当然,除非你已经实施了GitOps方法,在基础设施中的所有变化都是用X作为代码完成的。我不得不采用这种方式来为我们的基础设施透明地配置一切。

一个有趣的观察,那几个直接用手去操作基础设施的人开始更谨慎地使用控制台,包括我。
在一个中心位置运行整个基础设施的Bash命令是一个很好的选择,特别是当你的基础设施可能有很多服务器,而你还没有使用协调系统的时候。

在这篇文章中,我们将看一下对一台服务器的逐步配置,以便在控制台中显示所有输入的命令。上述所有命令最好与自动基础设施配置一起使用,因为在每台服务器上配置这种功能需要很长的时间。

在这篇文章中,我使用各种技术来设置Bash shell的日志,并将这些日志转发给Grafana。Grafana和Loki是在一个单独的监控服务器上。这使得我们很容易演示如何设置Bash日志的各种组件,并且应该很容易在你自己的基础设施中复制这种功能。上述所有的脚本和命令最好与自动基础设施配置一起使用,因为在每台服务器上单独配置这个功能需要很长的时间。

让我们开始吧!

初始数据:
服务器1:实验性服务器,我们将把它的bash历史推送到监控中;这样的服务器可以有很多,只要你喜欢。身份设置。
服务器2: 带有Grafana的监控服务器,我们将在这里安装Loki。

服务器1。设置操作员的bash环境

确保你安装了rsyslog。

apt-get install -y update && apt-get install -y rsyslog

PROMPT_COMMAND

为了设置bash日志,我们将使用PROMPT_COMMAND环境变量。PROMPT_COMMAND的内容将在Bash提示符返回之前被执行(也就是在终端的每个交互式命令被执行之后)。这个Bash功能将允许我们通过本地对象发送日志,并使用rsyslog将其写入日志文件。最后,我们将使用Promtail来转发Loki的日志,并在Grafana中显示它们。

要用PROMPT_COMMAND设置环境变量,请添加以下几行到 /etc/bash.bashrc。

export PROMPT_COMMAND=’RETRN_VAL=$?; if [ -f /tmp/lastoutput.tmp ]; then LAST_OUTPUT=$(cat /tmp/lastoutput.tmp); rm /tmp/lastoutput.tmp; fi; logger -S 10000 -p local6.debug “{\”user\”: \”$(whoami)\”, \”path\”: \”$(pwd)\”, \”pid\”: \”$$\”, \”b64_command\”: \”$(history 1 | sed “s/^[ ]*[0–9]\+[ ]*//” | base64 -w0 )\”, \”status\”: \”$RETRN_VAL\”, \”b64_output\”: \”$LAST_OUTPUT\”}”; unset LAST_OUTPUT;

其中。

RETRN_VAL=$?。-设置一个包含前一个命令运行的返回值的变量。因为PROMPT_COMMAND是在我们的提示符重新显示之前运行的,这最终意味着脚本将在我们运行的每个命令之后运行。

if [ -f /tmp/lastoutput.tmp ]; then LAST_OUTPUT=$(cat /tmp/lastoutput.tmp); rm /tmp/lastoutput.tmp;fi; - 检查是否存在一个名为/tmp/lastoutput.tmp的文件,将LAST_OUTPUT的值设置为该文件的内容值,如果存在则删除该文件。这个文件将通过我们稍后创建的一个实用函数来存储我们的命令的输出。

***logger -S 10000 -p local6.debug -***使用最多10000个字符的logger命令,并将优先级设置为本地对象local6.debug的级别。这将允许我们以后使用rsyslog来捕获日志。

"{\"user\"。\{fnTahomafs10bord0shad01cH00FFFF}{\"user\":"(whoami)\\", {fnTahomafs10bord0shad01cH00FFFF}}{"path\\":\\"(pwd)\", \"pid\":\"$$\", \"b64_command\":\(history 1 | sed -r "s/^\\s\*\[0-9\]+\\s\*//" | base64 -w0 )\\",\\"status\\":\\”RETRN_VAL\”, \\”b64_output\”:\"$last_output\"}"; - 包含一条日志信息。在我们的案例中,我们使用的是JSON格式。这将使我们在构建ELK堆栈期间解析登录Logstash的时候更加容易。正如你应该看到的,我们正在注册6个字段,包括。

  • 当前用户
  • 当前路径
  • PID
  • 之前的运行命令提取了使用 *history*并进行base64编码。Base64编码确保命令在我们的JSON对象中被正确转义。
  • 前一个运行命令的返回值
  • 命令的base64编码输出(如果它存在的话)。我们将在后面深入研究这个字段。

unset LAST_OUTPUT。 - 我们禁用LAST_OUTPUT变量,这样它就不会在命令之间持续存在。

LAST_OUTPUT

现在我们可以设置我们的辅助函数来捕获我们的命令输出,这样我们就可以把它们发送给Loki。由于没有内置的方法来自动捕获命令的输出,我们必须执行两次命令或使用辅助函数来捕获PROMPT_COMMAND脚本中的输出。

以下命令必须包含在你的 /etc/bash.bashrc文件中。

logoutput() { output=$(while read input; do echo$input”; done < “${1:-/dev/stdin}”); echo -e “$output“; echo -e “$output” | head -c 10000 | base64 -w0 > /tmp/lastoutput.tmp; return $?; }

如图所示,logoutput命令捕获命令的输出或读取文件的内容,对前一万个字符进行base64编码,并将其写入*/tmp/lastoutput.tmp* (记住,这个文件之前在我们的PROMPT_COMMAND中使用过!)。这个辅助函数可以用在系统中的一个文件上,也可以传给STDOUT,以便于记录!

这就完成了我们需要对*/etc/bash.bashrc* 文件所做的修改,现在我们可以继续设置rsyslog。你需要确保你有以下内容加入到你的 /etc/bash.bashrc 配置。

export PROMPT_COMMAND=’RETRN_VAL=$?; if [ -f /tmp/lastoutput.tmp ]; then LAST_OUTPUT=$(cat /tmp/lastoutput.tmp); rm /tmp/lastoutput.tmp; fi; logger -S 10000 -p local6.debug “{\”user\”: \”$(whoami)\”, \”path\”: \”$(pwd)\”, \”pid\”: \”$$\”, \”b64_command\”: \”$(history 1 | sed “s/^[ ]*[0–9]\+[ ]*//” | base64 -w0 )\”, \”status\”: \”$RETRN_VAL\”, \”b64_output\”: \”$LAST_OUTPUT\”}”; unset LAST_OUTPUT; ‘

写入/var/log/bash/bash.log

为rsyslog监控本地对象local6,在以下文件中添加以下内容。 /etc/rsyslog.d/bash.conf:

local6.* /var/log/bash/bash.log

重新加载rsyslog。

service rsyslog restart

我们还需要为我们的日志添加logrotate,以避免无限期地存储它们。打开该***/etc/logrotate.d/rsyslog*** 文件,并在其中添加以下内容。

/var/log/bash/bash.log {    hourly    missingok    rotate 1    compress    delaycompress    notifempty    create 0600 promtail promtail    sharedscripts}

让我们检查一下它是如何工作的!

让我们看看在控制台中执行命令后,我们的日志是怎么写的。

cat /var/log/bash/bash.log

你应该在下面的截图中看到它。

设置Promtail

我们还需要安装promtail,它将获取我们的日志文件并直接发送给Loki。

# Downliading promtail binarywget https://github.com/grafana/loki/releases/download/v2.3.0/promtail-linux-amd64.zip

让我们把Promtail变成一个服务。要做到这一点,创建 /etc/systemd/system/promtail.service文件,并添加该内容。

[Unit]Description=Promtail serviceAfter=network.target

重读服务配置文件。

sudo systemctl daemon-reload

并创建一个配置文件 /usr/local/bin/config-promtail.yml的内容。

server:http_listen_port: 9080grpc_listen_port: 0

启动Promtail服务。

sudo service promtail start

是时候跳到下一个步骤了--设置监控。

服务器2.安装Loki并配置Grafana

Logging at Scale in Kubernetes using Grafana Loki | by Pavan Kumar | Nerd  For Tech | Medium

安装Loki。

# Downloading Loki binary fileswget https://github.com/grafana/loki/releases/download/v2.3.0/loki-linux-amd64.zip

我们把Loki作为一个服务--创建 /etc/systemd/system/loki.service文件并添加内容。

[Unit]Description=Loki serviceAfter=network.target

创建一个配置文件 /usr/local/bin/config-loki.yml
并添加内容。

auth_enabled: false

在官方文档中阅读更多关于配置的内容。

为Loki索引创建一个目录。

mkdir /tmp/loki

接下来,重新启动守护进程。

sudo systemctl daemon-reload

并启动Loki服务。

sudo service loki enable && sudo service loki start

监控服务器上的Loki服务被配置为接收来自Promtail的日志。

让我们试着通过Grafana看到我们的bash历史
现在我们需要确保我们可以通过Grafana看到从服务器得到的日志。

登录Grafana,在数据源中添加一个新的Loki源:
配置->数据源->添加数据源->Loki,并在URL栏中添加http://localhost:3100 到URL字段中。
如下面的截图。

探索日志

要查看日志,点击侧边栏的探索按钮(🧭)。点击数据源,你可以看到一个日志文件的列表,选择其中一个来查看日志。你也可以像这样输入你自己的查询。 ***{filename="/var/log/bash/bash.log"}***将给出来自syslog的日志。

结语。下一步是什么?

将这种配置扩展到我们所有的云重定向器、本地操作等,使得跟踪正在进行的工作变得异常容易。这有时会让我们的生活更轻松。我希望这种方法能在某种程度上帮助你在Grafana中通过Promtail和Loki进行bash历史记录配置。

祝你设置愉快!