Skip to content

Commit bc58745

Browse files
Suma RSuma R
authored andcommitted
Automation to set size for log rotate and parse dbg logs for specific strings
Signed-off-by: Suma R <sumar@Sumas-MacBook-Pro.local>
1 parent 58d6d99 commit bc58745

File tree

3 files changed

+157
-4
lines changed

3 files changed

+157
-4
lines changed

suites/squid/cephfs/tier-3_cephfs_system_test.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,15 @@ tests:
215215
config:
216216
ENABLE_LOGS : 1
217217
daemon_list : ['mds','client','osd','mgr','mon']
218-
daemon_dbg_level : {'mds':20,'client':20,'osd':10,'mgr':10,'mon':10}
218+
daemon_dbg_level : {'mds':10,'client':10,'osd':5,'mgr':5,'mon':5}
219+
- test:
220+
abort-on-fail: false
221+
desc: "Set size limit for log rotation"
222+
name: size limit for log rotation
223+
module: cephfs_logs_util.py
224+
config:
225+
LOG_ROTATE_SIZE : 1
226+
log_size : '200M'
219227
-
220228
test:
221229
abort-on-fail: false
@@ -294,3 +302,12 @@ tests:
294302
config:
295303
DISABLE_LOGS : 1
296304
daemon_list : ['mds','client','osd','mgr','mon']
305+
-
306+
test:
307+
name: Parse dbg logs for specific strings
308+
module: cephfs_logs_util.py
309+
config:
310+
LOG_PARSER : 1
311+
daemon : 'mds'
312+
expect_list : ['issue_new_caps','get_allowed_caps','"sending MClientCaps"','client_caps\(revoke']
313+
unexpect_list: ['Exception','assert']

tests/cephfs/cephfs_logs_util.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import traceback
33

4+
from tests.cephfs.cephfs_system.cephfs_system_utils import CephFSSystemUtils
45
from tests.cephfs.cephfs_utilsV1 import FsUtils
56
from utility.log import Log
67

@@ -9,8 +10,10 @@
910

1011
def run(ceph_cluster, **kw):
1112
"""
12-
This script is a wrapper to Logs enablement and Logs collection module available in cephfs_uitlsV1
13-
It can be included prior to test case execution to enable debug logs and post testcase execution to collect logs,
13+
This script is a wrapper to Logs enablement, and Logs collection module available in cephfs_uitlsV1, Log Rotation
14+
for size limit available in cephfs_system_utils
15+
It can be included prior to test case execution to enable debug logs and log rotation and post testcase execution
16+
to collect logs,
1417
PRETEST: To enable logs
1518
-----------------------
1619
- test:
@@ -19,6 +22,14 @@ def run(ceph_cluster, **kw):
1922
config:
2023
ENABLE_LOGS : 1
2124
daemon_dbg_level : {'mds':5}
25+
PRETEST: To rotate logs after size limit
26+
---------------------------------------
27+
- test:
28+
name: Set size limit for log rotation
29+
module: cephfs_logs_util.py
30+
config:
31+
LOGS_ROTATE_SIZE : 1
32+
log_size : '200M'
2233
POSTTEST: To collect logs
2334
-------------------------
2435
- test:
@@ -35,13 +46,24 @@ def run(ceph_cluster, **kw):
3546
config:
3647
DISABLE_LOGS : 1
3748
daemon_list : ['mds']
49+
POSTTEST: To parse debug logs for specific strings
50+
-------------------------
51+
- test:
52+
name: parse debug logs for specific strings
53+
module: cephfs_logs_util.py
54+
config:
55+
LOG_PARSER : 1
56+
daemon : 'mds'
57+
expect_list : ['issue_new_caps','get_allowed_caps','sending MClientCaps','client_caps(revoke']
58+
unexpect_list: ['Exception','assert']
3859
3960
This script will read input params ENABLE_LOGS,UPLOAD_LOGS and DISABLE_LOGS and invoke corresponding
4061
cephfs_utilsV1 module to perform the task. If UPLOAD_LOGS, script will print the path were logs are uploadded.
4162
4263
"""
4364
try:
4465
fs_util = FsUtils(ceph_cluster)
66+
fs_sys_util = CephFSSystemUtils(ceph_cluster)
4567
config = kw.get("config")
4668
clients = ceph_cluster.get_ceph_objects("client")
4769
log.info("checking Pre-requisites")
@@ -56,8 +78,14 @@ def run(ceph_cluster, **kw):
5678
daemon_dbg_level = config.get("daemon_dbg_level", {"mds": 5})
5779
daemon_list = config.get("daemon_list", ["mds"])
5880
enable_logs = config.get("ENABLE_LOGS", 0)
81+
log_rotate_size = config.get("LOG_ROTATE_SIZE", 0)
82+
log_size = config.get("log_size", "200M")
5983
disable_logs = config.get("DISABLE_LOGS", 0)
6084
upload_logs = config.get("UPLOAD_LOGS", 0)
85+
log_parser = config.get("LOG_PARSER", 0)
86+
log_daemon = config.get("daemon")
87+
expect_list = config.get("expect_list", [])
88+
unexpect_list = config.get("unexpect_list", [])
6189
log_str = (
6290
f"Test Params : ENABLE_LOGS : {enable_logs}, UPLOAD_LOGS:{upload_logs}"
6391
)
@@ -69,7 +97,10 @@ def run(ceph_cluster, **kw):
6997
log.info(f"Enabling debug logs on daemons : {daemon_dbg_level}")
7098
if fs_util.enable_logs(client1, daemon_dbg_level):
7199
assert False, "Enable logs failed"
72-
100+
if log_rotate_size == 1:
101+
log.info(f"Enable log rotation after size limit : {log_size}")
102+
if fs_sys_util.log_rotate_size(client1, size_str=log_size):
103+
assert False, f"log rotate enablement for size {log_size} failed"
73104
if upload_logs == 1:
74105
log_dir = os.path.dirname(log.logger.handlers[0].baseFilename)
75106
log.info(f"log path:{log_dir}")
@@ -80,6 +111,14 @@ def run(ceph_cluster, **kw):
80111
log.info(f"Disabling debug logs on daemons : {daemon_list}")
81112
if fs_util.disable_logs(client1, daemon_list):
82113
assert False, "Disable logs failed"
114+
if log_parser == 1:
115+
log.info(
116+
f"Parse {log_daemon} dbg logs for expected {expect_list} and unexpected {unexpect_list}"
117+
)
118+
if fs_sys_util.log_parser(
119+
client1, expect_list, unexpect_list, daemon=log_daemon
120+
):
121+
assert False, f"{log_daemon} log parser failed"
83122

84123
log.info("Testcase Results:")
85124
for res in results:

tests/cephfs/cephfs_system/cephfs_system_utils.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(self, ceph_cluster):
2525
Args:
2626
ceph_cluster (ceph.ceph.Ceph): ceph cluster
2727
"""
28+
self.ceph_cluster = ceph_cluster
2829
self.mons = ceph_cluster.get_ceph_objects("mon")
2930
self.mgrs = ceph_cluster.get_ceph_objects("mgr")
3031
self.mdss = ceph_cluster.get_ceph_objects("mds")
@@ -273,3 +274,99 @@ def wait_for_two_active_mds(
273274
time.sleep(retry_interval) # Retry after the specified interval
274275

275276
return False
277+
278+
def log_rotate_size(self, client, size_str="200M"):
279+
"""
280+
This mutility will enable log rotation when debug log file size reached the limit mentioned in 'size_str'
281+
Required_param : size_str, it should be size with units recognised by Ceph Cluster such as,
282+
200M , 500M, 1G ...
283+
"""
284+
out, rc = client.exec_command(sudo=True, cmd="ceph fsid -f json")
285+
fsid_out = json.loads(out)
286+
fsid = fsid_out["fsid"]
287+
mds_nodes = self.ceph_cluster.get_ceph_objects("mds")
288+
mgr_nodes = self.ceph_cluster.get_ceph_objects("mgr")
289+
osd_nodes = self.ceph_cluster.get_ceph_objects("osd")
290+
mon_nodes = self.ceph_cluster.get_ceph_objects("mon")
291+
log_rotate_file = f"/etc/logrotate.d/ceph-{fsid}"
292+
log_rotate_file_bkp = f"/etc/logrotate.d/ceph-{fsid}.backup"
293+
log_rotate_tmp = "/home/cephuser/log_rotate_tmp"
294+
crontab_str = f"2 * * * * /usr/sbin/logrotate {log_rotate_file} >/dev/null 2>&1"
295+
log_complete = []
296+
for log_node_list in [mds_nodes, mgr_nodes, osd_nodes, mon_nodes]:
297+
for log_node in log_node_list:
298+
if log_node.node.hostname not in log_complete:
299+
# on each node
300+
cmd = f"cp {log_rotate_file} {log_rotate_file_bkp}"
301+
out, _ = log_node.exec_command(sudo=True, cmd=cmd)
302+
cmd = rf"sed '/compress/i \ \size {size_str}' {log_rotate_file} > {log_rotate_tmp}"
303+
out, _ = log_node.exec_command(sudo=True, cmd=cmd)
304+
cmd = f"yes | cp {log_rotate_tmp} {log_rotate_file}"
305+
out, _ = log_node.exec_command(sudo=True, cmd=cmd)
306+
cmd = f"echo {crontab_str} > /home/cephuser/log_cron_file"
307+
out, _ = log_node.exec_command(sudo=True, cmd=cmd)
308+
cmd = "crontab /home/cephuser/log_cron_file"
309+
out, _ = log_node.exec_command(sudo=True, cmd=cmd)
310+
log_complete.append(log_node.node.hostname)
311+
return 0
312+
313+
def log_parser(self, client, expect_list, unexpect_list, daemon="mds"):
314+
"""
315+
This utility parsers through daemon debug logs mentioned in daemon_list and checks for
316+
expected and unexpected strings in logs.
317+
If expected strings found and unexpected strings not found, return pass as 0
318+
If unexpected strrings found and expected strings not found, return fail as 1
319+
Example usage:
320+
expect_list = ['issue_new_caps','get_allowed_caps','sending MClientCaps','client_caps(revoke']
321+
unexpect_list = ['Exception','assert']
322+
log_parser(expect_list,unexpect_list)
323+
"""
324+
out, rc = client.exec_command(sudo=True, cmd="ceph fsid -f json")
325+
fsid_out = json.loads(out)
326+
fsid = fsid_out["fsid"]
327+
daemon_nodes = self.ceph_cluster.get_ceph_objects(daemon)
328+
log_path = f"/var/log/ceph/{fsid}"
329+
results = {"expect": {}, "unexpect": {}}
330+
for node in daemon_nodes:
331+
for search_str in expect_list:
332+
cmd = f"grep {search_str} {log_path}/*{daemon}*"
333+
try:
334+
out = node.exec_command(sudo=True, cmd=cmd)
335+
if len(out) > 0:
336+
log.info(
337+
f"Found {search_str} in {daemon} log in {log_path} on {node.node.hostname}:\n {out}"
338+
)
339+
results["expect"].update({search_str: node})
340+
except BaseException as ex:
341+
log.info(ex)
342+
for search_str in unexpect_list:
343+
cmd = f"grep {search_str} {log_path}/*{daemon}*"
344+
try:
345+
out, _ = node.exec_command(sudo=True, cmd=cmd)
346+
if len(out) > 0:
347+
log.error(
348+
f"Found {search_str} in {daemon} log in {log_path} on {node.node.hostname}:\n {out}"
349+
)
350+
results["unexpect"].update({search_str: node})
351+
except BaseException as ex:
352+
log.info(ex)
353+
expect_not_found = []
354+
unexpect_found = []
355+
for exp_str in expect_list:
356+
if exp_str not in results["expect"]:
357+
expect_not_found.append(exp_str)
358+
for unexp_str in unexpect_list:
359+
if unexp_str in results["expect"]:
360+
unexpect_found.append(unexp_str)
361+
test_status = 0
362+
if len(expect_not_found):
363+
log.error(
364+
f"Some of expected strings not found in debug logs for daemon {daemon}:{expect_not_found}"
365+
)
366+
test_status = 1
367+
if len(unexpect_found):
368+
log.error(
369+
f"Some of unexpected strings found in debug logs for daemon {daemon}:{unexpect_found}"
370+
)
371+
test_status = 1
372+
return test_status

0 commit comments

Comments
 (0)