终端日志采集及分析是一项重要的测试工作,设备异常的排查及版本升级都依赖于对日志的分析。当前日志采集通常采用手动的方式,对于采集到的日志,各模块开发了相应工具进行解析(如OneTrace)。然而,当前的日志分析流程需要手动抓取,因此不便于流程自动化。同时,当前的工作流程无法实时监控终端设备的状态信息。
为了实现上述需求,我们部署并开发了基于ELK系统的日志抓取及可视化分析工具,该工具能够实时监控设备的状态信息(充电状态,电量等)。当状态信息的变化触发了特定条件时,设备会自动抓取日志并传入Elasticsearch数据库。此外,该平台可以很方便地扩展至多设备而不需要额外的操作。
ELK是三个开源软件的缩写,分别表示:Elasticsearch, Logstash和Kibana , 它们都是Elastic公司开发的开源软件。
上述三种技术构成ELK技术栈,可以将各种日志进行收集、过滤、清洗,然后进行集中存放并可用于实时检索、分析。其中,Logstash担任控制层的角色,负责搜集和过滤数据。Elasticsearch担任数据持久层的角色,负责储存数据。Kibana担任视图层角色,拥有各种维度的查询和分析,并使用图形化的界面展示存放在Elasticsearch中的数据。
除了上述三个工具,Filebeat是隶属于Beats的轻量级数据收集引擎,用于转发和集中日志数据。Filebeat监视指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或Logstash进行索引。
下图展示了ELK架构的流程图,其涵盖了数据采集、过滤解析以及最终可视化呈现的流程。
安卓调试桥(Android Debug Bridge,简称ADB)是常用的安卓设备调试工具。通过ADB可以实现手机端的自动化控制和处理。而UIAutomator是Android官方推出的安卓应用界面自动化测试工具,能够根据文本、控件id、坐标进行点击、长按、滑动、查找等操作,实现与人一致的手动操作逻辑。本实验综合使用ADB+UIAutomator实现日志抓取操作和设备状态信息获取。
日志产生及传输的流程图见下图,日志从设备终端产生,通过宿主机最终传送到ELK所在服务器。在本实验中,ELK系统被部署在宿主机的虚拟机中。
结合设备控制功能与ELK框架,我们实现了设备日志产生到可视化的完整流程。为了排查设备异常,我部署了双节点Elasticsearch集群,分别用于存储设备状态信息和日志信息。当状态信息的变化触发特定条件时开始抓取日志信息。
宿主机操作系统:Windows10 64位
虚拟机操作系统:CentOS7 64位
WSL操作系统:Ubuntu 20.04.3 LTS 64位
ELK 版本:7.16.1
Python:3.7
UIAutomator2:2.16.17
ADB:33.0.2
从Vmware官网和阿里云开源镜像站分别下载VMware Workstation Pro 16和CentOS7的镜像文件,虚拟环境的部署流程见文章。
当虚拟机创建成功后,更改网络连接模式为NAT模式,这使得使用私有地址的内部网络连接到Internet或其它IP网络上。
查看宿主机和虚拟机是否处于同一个网段内,若不在同一网段,需要修改虚拟机的网段。
此时,宿主机的VMnet8网段和虚拟机网段相同,在宿主机使用ping命令向虚拟机IP发送数据。若能正常接收数据表示,宿主机能连接到虚拟机。
为了避免每次连接修改会话属性,需要固定虚拟机端口。修改配置文件/etc/sysconfig/network-scripts/ifcfg-ens33如下,保存配置文件后reboot重启虚拟机。
vi /etc/sysconfig/network-scripts/ifcfg-ens33
reboot
TYPE=“Ethernet”
PROXY_METHOD=“none”
BROWSER_ONLY=“no”
BOOTPROTO=“static”
IPADDR=“192.168.150.132”
DEFROUTE=“yes”
IPV4_FAILURE_FATAL=“no”
IPV6INIT=“yes”
IPV6_AUTOCONF=“yes”
IPV6_DEFROUTE=“yes”
IPV6_FAILURE_FATAL=“no”
IPV6_ADDR_GEN_MODE=“stable-privacy”
NAME=“ens33”
UUID=“168d7143-5fb4-4ebe-b570-c556cf77ebd0”
DEVICE=“ens33”
ONBOOT=“yes”
从Elastic官网分别下载Elasticsearch,Kibana,Filebeat和Logstash(版本均为7.16.1),解压至/home/user/Downloads路径下。首先需要更改文件操作权限为自定义用户,因为root权限下无法启用Elasticsearch。
chown user:user elasticsearch-7.16.1-linux-x86_64.tar.gz
其次,需要在解压前更改文件权限至755。
chmod 755 elasticsearch-7.16.1-linux-x86_64.tar.gz
解压Elasticsearch并拷贝一份Elasticsearch文件夹(代表2个节点),两个文件夹的名称分别位elasticsearch1和elasticsearch2。修改配置文件的方法如下:
cd /home/user/Downloads
vi ./elasticsearch1/config/elasticsearch.yml
vi ./elasticsearch2/config/elasticsearch.yml
两个节点的配置文件如下
cluster.name: cluster
node.name: node-1
node.master: true
node.data: true
node.max_local_storage_nodes: 2
network.host: 0.0.0.0
http.port: 9201
transport.tcp.port: 9700
discovery.seed_hosts: [“localhost:9700”,“localhost:9800”]
cluster.initial_master_nodes: [“node-1”, “node-2”]
path.data: /home/user/Downloads/elasticsearch1/data
path.logs: /home/user/Downloads/elasticsearch1/logs
cluster.name: cluster
node.name: node-2
node.master: true
node.data: true
node.max_local_storage_nodes: 2
network.host: 0.0.0.0
http.port: 9202
transport.tcp.port: 9800
discovery.seed_hosts: [“localhost:9700”,“localhost:9800”]
cluster.initial_master_nodes: [“node-1”, “node-2”]
path.data: /home/user/Downloads/elasticsearch2/data
path.logs: /home/user/Downloads/elasticsearch2/logs
之后启动两个节点,可以在浏览器获取到节点信息。
cd /home/user/Downloads
./elasticsearch1/bin/elasticsearch
cd /home/user/Downloads
./elasticsearch2/bin/elasticsearch
解压后修改Kibana的配置文件并在5601端口启用Kibana,可以在浏览器查看Kibana可视化界面。
cd /home/user/Downloads/kibana
vi ./config/kibana.yml
./bin/kibana
kibana.yml的内容如下
server.port: 5601
elasticsearch.hosts: [“http://localhost:9201”,“http://localhost:9202”]
对两个节点分别创建Logstash配置文件,配置文件中定义了文件解析格式,类型转换,输出索引等。本实验的目的是在设备状态变化时抓取日志,因此两个节点分别用于抓取设备状态信息和日志信息。其配置文件如下
input {
beats {
port => 5044
}
stdin{}
}
filter {
grok {
match => [
“message”,
“CHGR[\s(?\d+)\s/\s(? \d+)\s/\s(?\d+)\s/\s(? \d+)\s/\s(?\d+).*device:\s%{HOSTPORT:hostport}\s(? .+)”
]
}
mutate {
convert => [“[is_charging]”,“integer”]
remove_field => [message]
}
}
output {
elasticsearch {
index => “logstash-logs”
hosts => [“http://localhost:9201”]
user => elastic
password => “your password”
}
stdout {
codec => rubydebug
}
}
input {
beats {
port => 5045
}
stdin{}
}
filter {
grok {
match => [
“message”,
“level:\s(?\d+).*device:\s%{HOSTPORT:hostport}\s(?.+)”
]
}
mutate {
convert => [“[level]”,“integer”]
remove_field => [message]
}
}
output {
elasticsearch {
index => “logstash-state”
hosts => [“http://localhost:9202”]
user => elastic
password => “your password”
}
stdout {
codec => rubydebug
}
}
使用如下命令启用Logstash。此时,Elasticsearch数据库中会创建新的索引。
cd /home/user/Downloads/logstash1
./bin/logstash -f logstash-beats.conf
cd /home/user/Downloads/logstash2
./bin/logstash -f logstash-beats.conf
解压Filebeat压缩包后修改配置文件。状态信息和日志信息被存放在不同路径,所以在Filebeat中为两个节点设置不同的路径。具体配置文件如下
filebeat.inputs:
- type: log
enable: true
paths:
- /home/user/Downloads/data/logs/*.log
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.kibana:
output.logstash:
hosts: [“localhost:5044”]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
filebeat.inputs:
- type: log
enable: true
paths:
- /home/user/Downloads/data/state/*.log
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.kibana:
output.logstash:
hosts: [“localhost:5045”]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
启用Filebeat后可以在Logstash的页面看到每条日志的解析情况。因为符合解析格式的日志行在总日志中占比较少,因此会出现大量解析失败的情况。后续分析中需要在Kibana中剔除这部分日志,而仅关注正常解析的日志。
Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。WSL提供了一个微软开发的Linux兼容内核接口(不包含Linux代码),来自Ubuntu的用户模式二进制文件在其上运行。因为在Windows上安装sshpass命令出现问题,所以选择在Linux子系统中进行命令行控制。WSL安装的完整流程见此文章。
安装成功后在命令行输入wsl进入WSL,可以看到我们选用的操作系统是Ubuntu 20.04.3 LTS。
虚拟机只能被宿主机连接,如果想要被外部访问需要将主机的端口进行映射到虚拟机的ip和端口,这样就可以在局域网的其他设备通过主机的ip和端口访问虚拟机对应的端口。具体而言,后续改进需要将控制程序以应用的形式写入设备,从而各设备需要远程访问虚拟机。假设虚拟机IP为192.168.150.132,将宿主机的1992端口映射到虚拟机22端口的命令如下
netsh interface portproxy add v4tov4 listenport=1992
connectaddress=192.168.150.132 connectport=22
使用如下命令查看端口映射状态。
netsh interface portproxy show all
首先,需要将每台设备通过ADB命令与宿主机匹配并连接。
可以看到三台设备均通过局域网连接到宿主机,此时可以进行设备控制,设备控制代码基于ADB和UIAutomator。其中,UIAutomator用于连接设备,而ADB向手机输入命令。我们编写了代码以控制设备实现不同功能如进入开发者模式抓取模块日志。同时,我们还启用了多线程以控制多台设备。
该程序循环执行抓取状态信息和日志的功能。该过程中,手机被远程控制抓取日志,获取到的日志通过scp命令发送到宿主机。程序对宿主机中的状态信息和日志信息进行修改后发送到ELK日志系统指定路径。被解析后的格式化数据被存储在Elasticsearch数据库中,可以通过Kibana展示。
ERROR: [1] bootstrap checks failed. You must address the points described in
the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: max virtual memory areas
vm.max_map_count [65530] is too low, increase to at least [262144]
该问题产生的原因是Elasticsearch用户拥有的内存权限太小,至少需要262144。需要在/etc/sysctl.conf配置文件中修改配置。
su root
vi /etc/sysctl.conf
sysctl -p
添加内容:
vm.max_map_count=262144
保存后退出,并用以下命令启用Elasticsearch集群
su user
cd /home/user/Downloads/elasticsearch1/bin
./elasticsearch
su user
cd /home/user/Downloads/elasticsearch2/bin
./elasticsearch
[1]: max file descriptors [4096] for elasticsearch process is too low,
increase to at least [65535]
该问题产生的原因是最大文件描述符的数量太低,至少需要65536。因此,我们在/etc/security/limits.conf配置文件中修改配置。
su root
vi /etc/security/limits.conf
写入如下配置后保存并退出。
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
之后重启Linux使配置生效。
Logstash could not be started because there is already another instance
using the configured data directory. If you wish to run multiple instances,
you must change the “path.data” setting.
该问题产生的原因是之前运行的实例有缓存,保存在path.data里面有.lock文件(隐藏文件)。将其删除后重启logstash 即可。
cd /home/user/Downloads/logstash1/data
rm -rf .lock
cd /home/user/Downloads/logstash1
./bin/logstash -f logstash-beats.conf
cd /home/user/Downloads/logstash2/data
rm -rf .lock
cd /home/user/Downloads/logstash2
./bin/logstash -f logstash-beats.conf
由于Filebeat每次运行会产生一个registry文件,记录文件读取情况,重新运行会从上次结束的地方继续,导致没有数据量。所以每次停止Filebeat时都必须删除registry,并在Kibana中删除索引,然后再重运行Filebeat,以重新读取完整文件。
cd /home/user/Downloads/filebeat1/data
rm -rf registry
cd /home/user/Downloads/filebeat1
./filebeat --e --c filebeat.yml
cd /home/user/Downloads/filebeat2/data
rm -rf registry
cd /home/user/Downloads/filebeat2
./filebeat --e --c filebeat.yml
当启用Filebeat和Logstash后,Kibana上看不到对应的索引,分别测试Filebeat和Logstash配置是否正确。具体方法为在Logstash界面手动输入日志数据,观察Kibana是否产生对应索引。
可以看到,手动输入的日志能够被正常解析并存储在Elasticsearch,这表明Logstash运行正常。之后验证Filebeat是否正常运行。修改Filebeat的配置文件,改为输出到Elasticsearch。
cd /home/user/Downloads/filebeat1
vi filebeat.yml
将修改配置文件如下
filebeat.inputs:
- type: log
enable: true
paths:
- /home/user/Downloads/data/state/*.log
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.kibana:
output.elasticsearch:
hosts: [“localhost:9201”]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
可以看到Filebeat抓取的日志正常发送到了Elasticsearch数据库,表明Filebeat正常工作。此时,Filebeat和Logstash连接失败的唯一原因是端口被占用,解决方法是找到占用端口的进程并将其终止。
进程被终止后,再次启动Logstash和Filebeat,在Kibana中观察到产生索引,问题解决。
因为在Windows 无法保存 WSL的文件,所以需要赋予WSL默认root权限。解决方法为找到ubuntu可执行文件并配置默认用户为root。
cd
D:\Users\Downloads\CanonicalGroupLimited.UbuntuonWindows_2004.2021.825.0\Ubuntu_2004.2021.825.0_x64
ubuntu.exe config --default-user root
因为Windows10具有保护机制,所以当基于虚拟化的安全在运行时,虚拟机无法使用。该问题的解决方法为关闭Hyper-
V并修改注册表属性。首先在控制面板中找到Windows功能,将Hyper-V取消勾选。
打开注册表编辑器,找到以下路径
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard
新建四项DWORD(32位)
ConfigureSystemGuardLaunch 数值数据为 2
EnableVirtualizationBasedSecurity 数值数据为 0
RequireMicrosoftSignedBootChain 数值数据为 1
RequirePlatformSecurityFeatures 数值数据为 0
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
同样新建DWORD(32位)
LsaCfgFlags 数值数据为 0
bcdedit /set hypervisorlaunchtype off
将VMware Authorization Service关闭后重启。
打开系统信息查看基于虚拟化的安全性此时已经显示“未启用”。
再次打开虚拟机,此时已经可以正常使用。
当创建虚拟机时,选择网络时出现无法连接ens33,该问题是因为宿主机网络适配器缺少VMware Network Adapter VMnet1和VMware Network Adapter VMnet8。宿主机的网络适配器通过以下命令查看。
ipconfig /all
该问题的根本原因是卸载VMware Workstation后还留有残余的注册表文件,当再次安装VMware
Workstation时,这两个网络适配器仍然不存在。该问题的解决方案如下。
首先,卸载VMware Workstation。进入以下路径
控制面板\所有控制面板项\程序和功能
找到VMware Workstation选择更改并删除。
其次,进入服务界面。找到Device lnstall Service和Device Setup Manager,分别将其启动类型设为自动。
然后,安装Everything。用管理员身份打开Everything,找到和vmware相关文件并全部删除。
最后,安装CCleaner。选择注册表,点击扫描,待扫描完成后点击清理。至此,已经清理了残余的注册表文件。重新安装VMware Workstation即可正常连接ens33。
本实验提供了基于ELK系统的日志自动化抓取及可视化解决方案。具体而言,设备控制部分使用ADB+UIAutomator,通过程序将日志抓取,文件发送等操作自动化。数据存储及可视化部分使用ELK日志采集系统。其中,Elasticsearch用于数据存储和索引,Kibana用于数据可视化,Logstash和Filebeat分别用于解析和文件抓取。
本实验中使用三台测试机(Reno6 Pro+、A97和OnePlus 9RT)进行测试。测试过程中,宿主机和测试机连接至同一局域网。点击运行后,即可按相同时间间隔抓取状态信息和日志信息并进行处理。用户可在Kibana中的Discover界面进行数据可视化操作。
总体而言,该方案初步实现了多设备下的日志自动抓取和可视化分析,但是该方案还存在一些待改进之处。
首先,基于UIAutomator的设备控制存在连接中断的问题。一般情况下,连接中断时程序会重新启动UIAutomator直到恢复连接。然而,随着设备的增加,这种重连出现的频率明显增加,设备连接也更不稳定,从而无法在问题出现时抓取实时日志文件。
其次,当连接设备增多时,需要将各设备都与宿主机匹配并连接。同时,连接设备的局域网不能是公开的网络如OPPO-TEST,否则会匹配失败。
最后,手机关机重启后连接将会断开,因此每次使用之前都需要重新手动匹配。
以上三点问题对设备扩展造成了很大的影响。我们提出的解决方案为将远程控制程序以apk的形式传入手机,通过运行手机程序以实现上述相同的功能。
[1] Linux安装Elasticsearch(手把手入门教程及下载资源). https://blog.csdn.net/qq_45502336/article/details/122023493
[2] Elasticsearch Linux安装详细步骤. https://blog.csdn.net/weixin_49211575/article/details/110199107?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-6-110199107-blog-122023493.pc_relevant_multi_platform_whitelistv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-6-110199107-blog-122023493.pc_relevant_multi_platform_whitelistv1&utm_relevant_index=10
[3] linux 安装npm. https://blog.csdn.net/qq_36025814/article/details/122908298
[4] linux 卸载nodejs_linux 卸载安装node npm. https://blog.csdn.net/a15608445683/article/details/122459725
[5] Linux环境下安装Elasticsearch,史上最详细的教程来啦~. https://blog.csdn.net/smilehappiness/article/details/118466378
[6] filebeats 抽取log 文本到elasticsearch. https://www.jianshu.com/p/f51ca5d2f564
[7] filebeat零基础安装教程. https://blog.csdn.net/u013699761/article/details/124021686
[8] Logstash:用 Filebeat 把数据传入到 Logstash. https://blog.csdn.net/UbuntuTouch/article/details/100675502
[9] grok测试. https://www.csdn.net/tags/Mtjagg1sNDgxNTctYmxvZwO0O0OO0O0O.html
[10] Filebeats采集日志到ES. https://wenku.baidu.com/view/4ab5fe74a75177232f60ddccda38376baf1fe0ed?aggId=60d0040f925f804d2b160b4e767f5acfa1c7836b
[11] 适用于 Linux 的 Windows 10/11 子系统(WSL2)安装指南. https://blog.csdn.net/m0_63969219/article/details/124632640
[12] wsl使用root用户. https://www.csdn.net/tags/OtDacg4sODA5MzUtYmxvZwO0O0OO0O0O.html
[13] ssh远程连接虚拟机. https://blog.csdn.net/qzw752890913/article/details/119320506
[14] 您的主机不满足在启用 Hyper-V 或 Device/Credential Guard 的情况下运行 VMware Workstation的最低要求. https://blog.csdn.net/TATYBOY/article/details/121573228
[15] VMware Workstation虚拟机安装Linux CentOS 7镜像文件(带图形可视化界面). https://blog.csdn.net/weixin_44904239/article/details/124902694
[16] ElasticSearch 集群搭建. https://blog.csdn.net/weixin_52851967/article/details/124371851
[17] 从外部访问本机vmware虚拟机的方法. https://blog.csdn.net/shakspers/article/details/124187420
[18] 完美解决VMware安装后没有VMnet1和VMnet8的问题. https://blog.csdn.net/m0_60028455/article/details/124928272