shell 命令行实时打印docker 状态,并添加当前的时间戳,变成json字符串,每行一个,持续不停的输出。
结果将给filebeat 采集并实时送到kafka 集群做实时数据流分析的源头,发给Flink 做各种实时数据流分析.
这个看起来很简单,其实要实现起来难度不小,尝试了多次都失败了,
只是目标不断的趋近,到此刻终于彻底解决了这个问题。
- 禁止stdio缓存
- 实时输出
- docker stats 前面添加一个时间戳,而不是由filebeat 添加,因为这个意义不一样,命令行代表的实时的事件,filebeat 添加时间戳代表的是filebeat 读取日志的时间。
- 各种linux 命令的管道应用要很熟悉
docker stats --format ',"ID": "{{ .ID }}","name": "{{.Name}}","cpu":"{{ .CPUPerc }}","memory":{"raw":"{{ .MemUsage }}","percent":"{{ .MemPerc }}"},"netIO":"{{.NetIO}}","blockIO":"{{.BlockIO}}","PIDs":"{{.PIDs}}" }' | stdbuf -oL -eL sed -e 's/\"/\\\"/g' | sed 's/\x1b//g' | sed 's/\[2J\[H//g' | xargs -L 1 echo `date +'{"time":"%Y-%m-%d %H:%M:%S"'` $1
如果要实时采集远程的docker 状态,可以使用非入侵方式
e$ ssh root@10.2.1.83 "docker stats --format ',"ID": "{{ .ID }}","name": "{{.Name}}","cpu":"{{ .CPUPerc }}","memory":{"raw":"{{ .MemUsage }}","percent":"{{ .MemPerc }}"},"netIO":"{{.NetIO}}","blockIO":"{{.BlockIO}}","PIDs":"{{.PIDs}}" }' | stdbuf -oL -eL sed -e 's/\"/\\\"/g' | sed 's/\x1b//g' | sed 's/\[2J\[H//g' | xargs -L 1 echo `date +'{"time":"%Y-%m-%d %H:%M:%S"'` $1"
结果如下
如果要把结果保存到本地的文件
ssh root@10.2.1.83 "docker stats --format ',"ID": "{{ .ID }}","name": "{{.Name}}","cpu":"{{ .CPUPerc }}","memory":{"raw":"{{ .MemUsage }}","percent":"{{ .MemPerc }}"},"netIO":"{{.NetIO}}","blockIO":"{{.BlockIO}}","PIDs":"{{.PIDs}}" | stdbuf -oL -eL sed -e 's/\"/\\\"/g' | sed 's/\x1b//g' | sed 's/\[2J\[H//g' | xargs -L 1 echo `date +'{"time":"%Y-%m-%d %H:%M:%S"'` $1" >/tmp/1.log
可以使用tail -f 实时查看
上面代码有个问题,就是返回的双引号被xargs删除了,这个不是预期的理想结果,
修改如下: 使用#替换",然后再替换回来.
ssh root@10.2.1.81 " docker stats --format ‘,#ID#: #{{ .ID }}#,#name#: #{{.Name}}#,#cpu#:#{{ .C#{{.BlockIO}}#,#PIDs#:#{{.PIDs}}# }’ | stdbuf -oL -eL sed -e ‘s/#/\#/g’ | xargs -L 1 echo date +'{#time#:#%Y-%m-%d %H:%M:%S#'
$1 | sed -e ‘s/#/"/g’"
到这里,结果相对就比较完美了.
ssh root@10.2.1.81 " docker stats --format ‘,#ID#: #{{ .ID }}#,#name#: #{{.Name}}#,#cpu#:#{{ .CPUPerc }}#,#memory#:{#raw#:#{{ .MemUsage }}#,#percent#:#{{ .MemPerc }}#},#netIO#:#{{.NetIO}}#,#blockIO#:#{{.BlockIO}}#,#PIDs#:#{{.PIDs}}# }’ | stdbuf -oL -eL sed -e ‘s/#/\#/g’ | xargs -L 1 echo date +'{#time#:#%Y-%m-%d %H:%M:%S#'
$1 | sed -e ‘s/#/"/g’" > /tmp/docker_container/docker_container1.log
ssh root@10.2.1.82 " docker stats --format ‘,#ID#: #{{ .ID }}#,#name#: #{{.Name}}#,#cpu#:#{{ .CPUPerc }}#,#memory#:{#raw#:#{{ .MemUsage }}#,#percent#:#{{ .MemPerc }}#},#netIO#:#{{.NetIO}}#,#blockIO#:#{{.BlockIO}}#,#PIDs#:#{{.PIDs}}# }’ | stdbuf -oL -eL sed -e ‘s/#/\#/g’ | xargs -L 1 echo date +'{#time#:#%Y-%m-%d %H:%M:%S#'
$1 | sed -e ‘s/#/"/g’" > /tmp/docker_container/docker_container2.log
ssh root@10.2.1.83 " docker stats --format ‘,#ID#: #{{ .ID }}#,#name#: #{{.Name}}#,#cpu#:#{{ .CPUPerc }}#,#memory#:{#raw#:#{{ .MemUsage }}#,#percent#:#{{ .MemPerc }}#},#netIO#:#{{.NetIO}}#,#blockIO#:#{{.BlockIO}}#,#PIDs#:#{{.PIDs}}# }’ | stdbuf -oL -eL sed -e ‘s/#/\#/g’ | xargs -L 1 echo date +'{#time#:#%Y-%m-%d %H:%M:%S#'
$1 | sed -e ‘s/#/"/g’" > /tmp/docker_container/docker_container3.log
这样我们就可以用一台机器ssh 登录到n台机器去采集docker 实时信息,然后通过filebeat 发送给 kafka,
然后让Flink 之类的流处理引擎做实时的处理和监控预警,实现更复杂的逻辑.