【问题标题】:Extract data from unix log file, construct JSON and perform post request using curl从 unix 日志文件中提取数据,构造 JSON 并使用 curl 执行 post 请求
【发布时间】:2021-01-04 08:43:29
【问题描述】:

我的总体任务是不断从 UNIX 系统日志文件中收集数据,对其进行过滤,根据过滤后的数据准备 json 有效负载,并通过向另一台服务器发送 post api 调用来处理数据。

我想知道是否可以使用shell脚本来监控带有tail的日志文件,使用grep过滤以将特定行转储到另一个文件中。使用 cronjob 运行另一个构建 .json 的脚本并将带有 json 的 curl 请求发送到外部服务器。

一些细节:

在日志文件中 - connector.log 我对以下行感兴趣:

2020-09-16T15:14:37,337 INFO  (tomcat-http--131) [tenant-test;-;138.188.247.4;] com.vmware.horizon.adapters.passwordAdapter.PasswordIdpAdapter - Login: user123 - SUCCESS 

这些行,我可以通过下面的命令来收集:

tailf connector.log | grep 'PasswordIdpAdapter - Login\|FAILURE\|SUCCESS'

并可能将它们转储到文件中:

tailf connector.log | grep 'PasswordIdpAdapter - Login\|FAILURE\|SUCCESS' > log_data.txt

此时我想知道,是否可以从 connector.log 的一行(而不是整行)中仅提取特定字段,因此 log_data.txt 中的一行看起来像( 1、4、6、7、8):

1 2020-09-29T07:15:13,881 [tenant1;usrname@tenant1;10.93.231.5;] - username - SUCCESS

从那时起,我需要编写一个脚本(也许可以由 cronjob 每分钟运行一次)/或一个命令来构造下面的 json 并发送请求。一行 - 一个请求。

这是json的例子:

{
   "timestamp": "2020-09-16T15:24:35,377",
   "tenant_name": "tenant-test",
   "log_type": "SERVICE",
   "log_entry": "Login: user123 - SUCCESS"
}

应该替换的字段值已经存在于日志行中:timestamp(第 1 个字段,例如 2020-09-16T15:14:37,337)、tenant_name(第 4 个字段的第 1 部分,tenant-test)和log_entry(最后四个字段,例如登录:user123 - SUCCESS)。

json 构造完成后,我会通过以下方式发送:

curl --header "Content-Type: application/json" --request POST --data \
  $payload http://myservert:8080/api/requests

我不清楚什么,这个脚本从 log_data.txt 中逐行获取数据,例如

并填充一些字段以创建 .json 并将其发送到服务器。

提前感谢您的回答, 佩特科

【问题讨论】:

  • 通过awk 管道传输数据流可以使用| awk {print $3, $5, $7} (等)选择单个字段,但您可能需要了解FS 变量(FieldSeperator)。通过Awk Tutorial 工作。这里的信息太多了。我们在这里帮助解决特定问题。您可能有一个特定的问题,但它被长时间的讨论所笼罩。并在鼠标选择的文本上使用编辑菜单中的{} 工具将格式设置为code/data/requiredOutput/ExactErrMsgs。祝你好运。
  • 先尝试自己实施解决方案,当您对正在编写的代码有具体的技术问题时,请来这里。如果您要解析日志、生成 json 并将其发送到 Web 服务,我建议您查看更高级的语言(python 等)而不是 shell。

标签: json linux shell unix curl


【解决方案1】:

感谢@shellter 的 awk 想法。因此,bash、awk、grep、cat、cut 和 curl 完成了这项工作。 我创建了一个 cronjob 以 5 分钟间隔执行 bash 脚本。

脚本获取最后 5 分钟的日志数据,将其转储到另一个文件,读取过滤后的数据,准备有效负载,然后执行 API 调用。也许这很愚蠢,但它确实有效。

#!/bin/bash

MONITORED_LOG="/var/logs/test.log"
FILTERED_DATA="/tmp/login/login_data.txt"
REST_HOST="https://rest-host/topics/logs-"

# dump the last 5 mins of log data(date format: 2020-09-28T10:52:28,334)
# to a file, filter for keywords FAILURE\|SUCCESS and NOT having 'lookup|SA' 
# an example of data record taken: 1 2020-09-29T07:15:13,881 [tenant1;usrname@tenant1;10.93.231.5;] - username - SUCCESS

awk -v d1="$(date --date="-5 min" "+%Y-%m-%dT%H:%M:%S")" -v d2="$(date "+%Y-%m-%dT%H:%M:%S")" '$0 > d1 && $0 < d2' $MONITORED_LOG | grep 'FAILURE\|SUCCESS' | grep -v 'lookup\|SA-' | awk '{ print $2, $3, $5, $7}' | uniq -c > $FILTERED_DATA

## loop through all the filtered records and send an API call
cat $FILTERED_DATA | while read LINE; do

## preparing the variables
timestamp=$(echo $LINE | cut -f2 -d' ')
username=$(echo $LINE | cut -f5 -d' ')
log_entry=$(echo $LINE | cut -f7 -d' ')
# get the tenant name, split by ; and remove the first char [ 
tenant_name=$(echo $tenant_name | cut -f1 -d';')
tenant_name="${tenant_name:1}"
    
# preparing the payload
payload=$'{"records":[{"value":{"timestamp":"'
payload+=$timestamp
payload+=$'","tenant_name":"'
payload+=$tenant_name
payload+=$'","log_entry":"'
payload+=$log_entry
payload+=$'"}}]}'
echo 'payload: ' $payload

# send the api call to the server with dynamic construction of tenant name
curl -i -k  -u 'api_user:3494ssdfs3' --request POST --header "Content-type:application/json" --data "$payload" "$REST_HOST$tenant_name"

完成

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多