从unix日志文件中提取数据,构造JSON并使用curl执行post请求

从unix日志文件中提取数据,构造JSON并使用curl执行post请求,json,linux,shell,unix,curl,Json,Linux,Shell,Unix,Curl,我的总体任务是不断地从UNIX系统日志文件收集数据,对其进行过滤,根据过滤后的数据准备json负载,并通过向另一台服务器发送post api调用来处理数据 我想知道是否可以使用shell脚本来监视带有tail的日志文件,使用grep进行过滤以将特定行转储到另一个文件中。使用cronjob运行另一个脚本,该脚本构造一个.json并将带有json的curl请求发送到外部服务器 一些细节: 在日志文件-connector.log中,我对以下行感兴趣: 2020-09-16T15:14:37,337 I

我的总体任务是不断地从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):

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

以下是json的示例:

{
   "timestamp": "2020-09-16T15:24:35,377",
   "tenant_name": "tenant-test",
   "log_type": "SERVICE",
   "log_entry": "Login: user123 - SUCCESS"
}
应该替换的字段值已经存在于日志行中:时间戳(第一个字段,例如2020-09-16T15:14:37337)、租户名称(第四个字段的第一部分,租户测试)和日志项(最后四个字段,例如登录:user123-SUCCESS)

构建json后,我将通过以下方式发送:

curl --header "Content-Type: application/json" --request POST --data \
  $payload http://myservert:8080/api/requests
我不清楚的是,这个脚本可以从log_data.txt逐行获取数据,例如

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

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

感谢@Shelleter提出的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"
#/bin/bash
监视的_LOG=“/var/logs/test.LOG”
筛选的_DATA=“/tmp/login/login_DATA.txt”
REST_主机=”https://rest-host/topics/logs-"
#转储最后5分钟的日志数据(日期格式:2020-09-28810:52:28334)
#对于文件,筛选关键字FAILURE\| SUCCESS和NOT have'lookup | SA'
#数据记录示例:1 2020-09-29T07:15:13881[1;usrname@tenant1;10.93.231.5;]-用户名-成功
awk-v d1=“$(日期--date=“-5分钟”+%Y-%m-%dT%H:%m:%S”)”-v d2=“$(日期”+%Y-%m-%dT%H:%m:%S”)“$0>d1和$0$
##循环遍历所有筛选的记录并发送API调用
cat$FILTERED|u DATA|在读取行时;做
##准备变量
时间戳=$(echo$行| cut-f2-d'')
用户名=$(echo$行| cut-f5-d'')
log_条目=$(echo$行| cut-f7-d'')
#获取租户名称,按拆分;并删除第一个字符[
租户_名称=$(echo$tenant_名称| cut-f1-d';'))
租户名称=“${租户名称:1}”
#准备有效载荷
有效负载=$'{“记录”:[{“值”:{“时间戳”:“'
有效负载+=$timestamp
有效负载+=$”,“租户名称”:“'
有效负载+=$tenant\u名称
有效负载+=$”,“日志项”:“'
有效负载+=$log\u项
有效负载+=$'“}}]}”
echo“有效负载:”$payload
#使用租户名称的动态构造将api调用发送到服务器
curl-i-k-u'api\u user:3494ssdfs3'--请求发布--标题“内容类型:应用程序/json”--数据“$payload”“$REST\u主机$tenant\u名称”

完成

通过
awk
管道传输数据流可以使用
|awk{print$3、$5、$7}
(等)选择单个字段,但您可能需要了解FS变量(fieldseparator).一路工作。这里的信息太多了。我们来这里是为了帮助解决特定的问题。您可能有特定的问题,但由于长时间的讨论,它被蒙上了阴影。请使用
{}
鼠标编辑菜单中的工具选择文本格式为
code/data/requiredOutput/ExactErrMsgs
。祝你好运。首先尝试自己实现一个解决方案,当你对正在编写的代码有特定的技术问题时,请来到这里。我建议你使用更高级的语言(python等)如果要解析日志、生成json并将其发送到web服务,则不使用shell。
#!/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"