在使用locust壓測的時候,若是使用web則能夠查看到QPS壓測過程的曲線圖。而若是使用no web模式啓動,則只有一些打印的日誌能夠查看。php
那麼可否將no web模式啓動的locust執行過程日誌轉化爲曲線圖表呢?python
若是須要將日誌轉化爲曲線圖表,那麼則如下步驟: 一、將locust執行任務日誌序列化,方便程序讀取 二、須要定時刷新獲取執行日誌文件,將日誌信息寫入數據庫 三、讀取數據庫數據,將其進行圖表化呈現。web
而且還要求這個日誌採集處理要足夠輕量級、資源消耗小,只有在執行locust的時候才啓動便可。因此,我也放棄了filebeat + logstash + Elasticsearch 或者 kafka 、redis等大型採集日誌的方案。redis
本身定製化寫一個便可。shell
對於locust執行任務的日誌序列化我嘗試過直接在locust源碼中掛上鉤子,而後將日誌進行格式化以後,再寫入一個文件中。 功能上是能夠實現的,可是壓測性能上就會大打折扣,因爲locust在壓測過程須要對每一個壓測請求都進行格式化以及寫入文件,這樣就很影響壓測機的併發效率。數據庫
因此這種方式已經被我拋棄。api
有興趣能夠參考:Matplotlib可視化查看Locust測試結果(一)bash
在通過多測壓測測試以後,我決定直接使用locust執行過程打印的日誌來生成圖表。併發
一、首先將locust執行過程的日誌寫入文件中 二、經過讀取執行文件的日誌信息,再將其轉化存儲到influxdb數據庫 三、最後根據influxdb數據庫的數據,展現圖表curl
在這個過程,對於locust自身的壓測過程,我並無嵌入代碼去影響執行效率。而是將locust執行過程自動打印出來的信息進行二次處理而已。
這樣作的好處就是不會對locust壓測形成較大的性能損耗,由於大概是5秒打印一次執行日誌,相信這個損耗是比較低的了。
原生的locust執行日誌:
能夠從圖中看到,在執行locust腳本使用no web模式的時候,執行的日誌默認是INFO級別的,通常咱們都是這樣去使用。 此時,INFO的日誌信息和locust壓測執行結果混合在一塊兒打印,這就讓人很不開心了。因此必須將其分開。
首先肯定我只須要的信息,以下:
若是壓測的接口有多個,那麼就會有對應的多條信息。示例以下:
Name # reqs # fails Avg Min Max | Median req/s
--------------------------------------------------------------------------------------------------------------------------------------------
GET /apis1 988 0(0.00%) 20 5 73 | 16 97.12
--------------------------------------------------------------------------------------------------------------------------------------------
GET /apis2 988 0(0.00%) 20 5 73 | 16 97.12
--------------------------------------------------------------------------------------------------------------------------------------------
Total 988 0(0.00%) 97.12
複製代碼
肯定好了須要的數據日誌信息以後,下面第一步就是能夠將INFO信息和執行結果信息拆分寫入不一樣的日誌文件中。
拆分日誌中的INFO信息與執行結果信息
--logfile=locust.log --loglevel=INFO
將INFO
信息寫到locust.log
日誌中1>run.log 2>&1
將壓測執行的結果信息寫到run.log
日誌中命令執行以下: locust -f locustfile.py --no-web -c 100 -r 50 --run-time=30 --expect-slaves=2 --csv=result --host='http://127.0.0.1:8000' --logfile=locust.log --loglevel=INFO 1>run.log 2>&1
查看執行壓測結果日誌run.log
以下:
查看執行INFO信息日誌locust.log
以下:
能夠看到INFO信息和locust執行的壓測結果已經分開日誌文件存儲好了。那麼下面就須要想辦法將執行壓測結果的數據進行序列化讀取,存儲到influxdb中。
在這裏能夠寫一個簡單的功能,以下:
下面直接將實現好的python代碼show出來,以下:
import subprocess
import re
import os
def main():
# 實時讀取日誌信息
shell = 'tail -F run.log'
p = subprocess.Popen(shell, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
line = line.rstrip().decode('utf8')
# print(line)
# 正則匹配獲取全部的須要參數
res = re.match(
r'^\s+(?P<method>GET|POST)\s+(?P<api>[\/\w\?\=\&]+)\s+(?P<reqs>\d+)\s+(?P<fails>[\d\(\.\)\%]+)\s+(?P<Avg>\d+)\s+(?P<Min>\d+)\s+(?P<Max>\d+)\s+(\|)\s+(?P<Median>\d+)\s+(?P<QPS>[\w\.]+)$',
line)
if res:
print("method: %s, api: %s, reqs: %s, fails: %s, Avg: %s, Min: %s, Max: %s, Median: %s, QPS: %s " % (
res.group('method'), res.group('api'), res.group('reqs'), res.group('fails').split('(')[0], res.group('Avg'),
res.group('Min'), res.group('Max'), res.group('Median'), res.group('QPS')
))
# 設置須要寫入influxdb的參數
method = res.group('method')
api = res.group('api')
reqs = res.group('reqs')
fails = res.group('fails').split('(')[0]
avg = res.group('Avg')
min = res.group('Min')
max = res.group('Max')
median = res.group('Median')
qps = res.group('QPS')
# 往influxdb寫入數據
# 建立數據庫 curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE testdb"
# 插入數據
# 表名 索引 tag 字段 fields
# curl -i -XPOST 'http://localhost:8086/write?db=testdb' --data-binary 'locust,method=GET,api=/apis reqs=2099,fails=10,avg=20,min=5,max=83,median=16,qps=95.10'
database = 'testdb'
table_name = 'locust'
insert_data = "curl -i -XPOST 'http://localhost:8086/write?db=%s' --data-binary '%s,method=%s,api=%s reqs=%s,fails=%s,avg=%s,min=%s,max=%s,median=%s,qps=%s'" % (database,table_name,method,api,reqs,fails,avg,min,max,median,qps)
os.system(insert_data)
if __name__ == '__main__':
main()
複製代碼
此時執行的參數已經能夠實時寫入influxdb中了,以下:
> precision rfc3339
>
> select * from locust limit 10 tz('Asia/Shanghai')
name: locust
time api avg fails max median method min qps reqs
---- --- --- ----- --- ------ ------ --- --- ----
2019-11-21T14:59:19.040228993+08:00 /apis 16 0 43 14 GET 6 0 191
2019-11-21T14:59:21.039195477+08:00 /apis 62 0 206 55 GET 6 36 481
2019-11-21T14:59:23.059811043+08:00 /apis 151 0 1305 110 GET 6 96.2 765
2019-11-21T14:59:25.077216006+08:00 /apis 211 0 2098 160 GET 6 103.5 990
2019-11-21T14:59:27.066784427+08:00 /apis 272 0 4700 180 GET 6 110 1262
2019-11-21T14:59:29.061261969+08:00 /apis 384 0 6386 190 GET 6 126.1 1532
2019-11-21T14:59:31.079897673+08:00 /apis 395 0 9465 190 GET 6 133.4 1804
2019-11-21T14:59:33.076470655+08:00 /apis 422 0 9707 200 GET 6 132 2034
2019-11-21T14:59:35.084000478+08:00 /apis 526 0 13796 200 GET 6 127.1 2270
2019-11-21T14:59:37.102809695+08:00 /apis 574 0 15456 200 GET 6 127.5 2553
>
複製代碼
那麼下一步只要在grafana展現圖表就能夠了。
先建立一個table表格,以下:
將查詢語句直接寫入查詢框中,而後選擇數據庫(我前面已經設置好,這裏就不展現了),最後設置查詢的時間,就能夠看到數據展現了。
最後修改標題,保存起來就能夠了,下面再來作一個折線圖。
一樣的操做,如何須要在折線圖上顯示什麼曲線,那就增長字段便可。在複製到grafana以前,最好在influx查詢執行一下,看看可否執行成功。
個人測試執行以下:
> select "qps","avg" from locust limit 5 tz('Asia/Shanghai')
name: locust
time qps avg
---- --- ---
2019-11-21T14:59:19.040228993+08:00 0 16
2019-11-21T14:59:21.039195477+08:00 36 62
2019-11-21T14:59:23.059811043+08:00 96.2 151
2019-11-21T14:59:25.077216006+08:00 103.5 211
2019-11-21T14:59:27.066784427+08:00 110 272
>
複製代碼
到這裏就已經實現locust執行日誌的實時查看了。
最後設置一下頁面自動刷新,以下:
另外,若是有不清楚influxdb和grafana安裝和基本操做的,能夠看看我以前寫關於這兩個工具的篇章: Grafana系列 InfluxDB系列