文章目錄
- 1. 說明
- 2. 啟個 mysql
- 3. 設置慢查詢
- 4. filebeat 設置
- 5. 觸發慢查詢
- 6. MySQL 告警至飛書
1. 說明
elk 版本:8.15.0
2. 啟個 mysql
docker-compose.yml
中 mysql:
mysql:# restart: alwaysimage: mysql:8.0.27# ports:# - "3306:3306"volumes:- ./mysql/data:/var/lib/mysql- ./mysql/log:/var/log/mysqlcommand: ['--character-set-server=utf8mb4','--collation-server=utf8mb4_unicode_ci','--default-time-zone=+8:00']environment:TZ: "Asia/Shanghai"MYSQL_ROOT_PASSWORD: "Mysqlr00Tp"
啟動,并查看:
docker-compose up -d
docker-compose ps
3. 設置慢查詢
進入 mysql 查詢慢查詢設置,因為我這里是臨時測試,所以直接用命令設置,生產還需要設置到配置文件中。
# 我這里是 elk-mysql-1 容器名
docker exec -it elk-mysql-1 /bin/bash# 進入 mysql
mysql -uroot -p$MYSQL_ROOT_PASSWORD
查詢結果:
mysql> SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | OFF |
+----------------+-------+
1 row in set (0.01 sec)mysql> SHOW VARIABLES LIKE 'slow_query_log_file';
+---------------------+--------------------------------------+
| Variable_name | Value |
+---------------------+--------------------------------------+
| slow_query_log_file | /var/lib/mysql/1f4c6d344dcc-slow.log |
+---------------------+--------------------------------------+
1 row in set (0.00 sec)mysql> SHOW VARIABLES LIKE 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
把慢查詢開啟,并設置慢查詢時間為 2 秒:
mysql> SET GLOBAL slow_query_log = 'ON';
Query OK, 0 rows affected (0.02 sec)mysql> SET GLOBAL long_query_time = 2;
Query OK, 0 rows affected (0.00 sec)
慢查詢日志路徑不支持在線設置,需要設置到配置文件中,所以我們直接用上面默認的路徑測試。
mysql> SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log';
ERROR 1231 (42000): Variable 'slow_query_log_file' can't be set to the value of '/var/log/mysql/mysql-slow.log'
上面設置后,退出再重進下,生效到新 Session 中。
4. filebeat 設置
modules.d/mysql.yml
中設置:
- module: mysqlerror:enabled: falsevar.paths: ["/path/to/log/mysql/error.log*"]slowlog:enabled: truevar.paths: ["/data/docker/elk/mysql/data/*-slow.log*"]
因為這里是容器環境,默認錯誤日志是輸出的,我們只設置慢查詢日志就好。
mysql> SHOW VARIABLES LIKE 'log_error';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| log_error | stderr |
+---------------+--------+
1 row in set (0.00 sec)
主配置 filebeat.yml
:
filebeat.config.modules:# Glob pattern for configuration loadingpath: ${path.config}/modules.d/*.ymloutput.elasticsearch:hosts: ["https://10.1.205.165:9200"]username: "filebeat_writer"password: "YOUR_PASSWORD"ssl:enabled: true# fingerprint=$(openssl x509 -fingerprint -sha256 -noout -in certs/ca/ca.crt | awk -F"=" '{print $2}' | sed 's/://g')ca_trusted_fingerprint: "33CB5A3B3ECCA59FDF7333D9XXXXXXXXFD34D5386FF9205AB8E1"# certs/ca 目錄從 es 中拷過來certificate_authorities: ["certs/ca/ca.crt"]# output.logstash:
# hosts: ["10.1.205.165:5044", "10.1.205.166:5044"]setup.kibana:host: "10.1.205.165:5601"logging.level: warning
啟動 filebeat 即可。
5. 觸發慢查詢
用以下 SQL 觸發慢查詢:
CREATE DATABASE test;
USE test;CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY,data VARCHAR(255)
);INSERT INTO test_table (data) VALUES ('sample data 1'), ('sample data 2'), ('sample data 3');SELECT SLEEP(3), data FROM test_table;
在 MySQL 中,SLEEP
函數的參數是以秒為單位的。如果你執行 SELECT SLEEP(3), data FROM test_table;
,每一行都會等待 3 秒。因此,如果表中有 3 行數據,總的查詢時間將是 3 秒乘以行數,即 9 秒。
可以看到 kibana 中的 dashboard 已經有數據了:
6. MySQL 告警至飛書
docker-compose.yml
:
services:elastalert:image: ygqygq2/elastalert2:2.21.0volumes:- ./elastalert/config.yaml:/opt/elastalert/config.yaml- ./elastalert/rules:/opt/elastalert/rules- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:rorestart: always
關鍵的是 rules:
#rule name 必須是獨一的,不然會報錯
name: "mysql-slowlog"
type: "frequency"
#這個index 是指再kibana 里邊的index 支持正則 log-*
index: "filebeat-*"
#時間觸發的次數
num_events: 1
#和num_events參數關聯,1分鐘內出現1次會報警
timeframe:# hours: 1minutes: 1# seconds: 30
##同一規則的兩次警報之間的最短時間。在此時間內發生的任何警報都將被丟棄。默認值為一分鐘
realert:minutes: 1
# terms_size: 50
# timestamp_field: "@timestamp"
# timestamp_type: "iso"
use_strftime_index: truefilter:- query:bool:must:- query_string:query: "event.dataset: mysql.slowlog"- script:script:source: >def ip_list = params.ip_list;def host_ip = doc['host.ip'][0];def duration_in_seconds = doc['event.duration'].value / 1e9;return ip_list.contains(host_ip) && duration_in_seconds > params.threshold;lang: painlessparams:ip_list: ["10.x.x.x"]threshold: 10 # 10 secondsalert:- feishu# 告警群
feishu_robot_webhook_url: "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx"# 這個時間段內的匹配將不告警,適用于某些時間段請求低谷避免誤報警
# feishu_skip:
# start: "01:00:00"
# end: "09:00:00"alert_subject: "MySQL 慢查詢"
alert_text_type: alert_text_only
alert_text: |💔 ELK 日志告警🔵【告警名稱】{}🧭【告警時間】{}🔢【命中次數】{}🆔【日志_id】{}🖥??【故障主機】{}🌐【查詢來源】{}👤【查詢用戶】{}??【查詢耗時】{} 秒📝【日志信息】{}# 設置告警使用的變量名
alert_text_args:- "alert_subject"- "alert_time"- "num_hits"- "_id"- "host.ip[0]"- "related.ip"- "related.user"- "event.duration"- "mysql.slowlog.query"
參考資料:
[1] https://www.elastic.co/guide/en/beats/filebeat/8.15/filebeat-module-mysql.html