Skip to content

Commit 63a67a9

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 63a67a9

File tree

3 files changed

+156
-4
lines changed

3 files changed

+156
-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: 41 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,9 @@
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 to collect logs,
1416
PRETEST: To enable logs
1517
-----------------------
1618
- test:
@@ -19,6 +21,14 @@ def run(ceph_cluster, **kw):
1921
config:
2022
ENABLE_LOGS : 1
2123
daemon_dbg_level : {'mds':5}
24+
PRETEST: To rotate logs after size limit
25+
---------------------------------------
26+
- test:
27+
name: Set size limit for log rotation
28+
module: cephfs_logs_util.py
29+
config:
30+
LOGS_ROTATE_SIZE : 1
31+
log_size : '200M'
2232
POSTTEST: To collect logs
2333
-------------------------
2434
- test:
@@ -35,13 +45,24 @@ def run(ceph_cluster, **kw):
3545
config:
3646
DISABLE_LOGS : 1
3747
daemon_list : ['mds']
48+
POSTTEST: To parse debug logs for specific strings
49+
-------------------------
50+
- test:
51+
name: parse debug logs for specific strings
52+
module: cephfs_logs_util.py
53+
config:
54+
LOG_PARSER : 1
55+
daemon : 'mds'
56+
expect_list : ['issue_new_caps','get_allowed_caps','sending MClientCaps','client_caps(revoke']
57+
unexpect_list: ['Exception','assert']
3858
3959
This script will read input params ENABLE_LOGS,UPLOAD_LOGS and DISABLE_LOGS and invoke corresponding
4060
cephfs_utilsV1 module to perform the task. If UPLOAD_LOGS, script will print the path were logs are uploadded.
4161
4262
"""
4363
try:
4464
fs_util = FsUtils(ceph_cluster)
65+
fs_sys_util = CephFSSystemUtils(ceph_cluster)
4566
config = kw.get("config")
4667
clients = ceph_cluster.get_ceph_objects("client")
4768
log.info("checking Pre-requisites")
@@ -56,8 +77,14 @@ def run(ceph_cluster, **kw):
5677
daemon_dbg_level = config.get("daemon_dbg_level", {"mds": 5})
5778
daemon_list = config.get("daemon_list", ["mds"])
5879
enable_logs = config.get("ENABLE_LOGS", 0)
80+
log_rotate_size = config.get("LOG_ROTATE_SIZE", 0)
81+
log_size = config.get("log_size", "200M")
5982
disable_logs = config.get("DISABLE_LOGS", 0)
6083
upload_logs = config.get("UPLOAD_LOGS", 0)
84+
log_parser = config.get("LOG_PARSER", 0)
85+
log_daemon = config.get("daemon")
86+
expect_list = config.get("expect_list", [])
87+
unexpect_list = config.get("unexpect_list", [])
6188
log_str = (
6289
f"Test Params : ENABLE_LOGS : {enable_logs}, UPLOAD_LOGS:{upload_logs}"
6390
)
@@ -69,7 +96,10 @@ def run(ceph_cluster, **kw):
6996
log.info(f"Enabling debug logs on daemons : {daemon_dbg_level}")
7097
if fs_util.enable_logs(client1, daemon_dbg_level):
7198
assert False, "Enable logs failed"
72-
99+
if log_rotate_size == 1:
100+
log.info(f"Enable log rotation after size limit : {log_size}")
101+
if fs_sys_util.log_rotate_size(client1, size_str=log_size):
102+
assert False, f"log rotate enablement for size {log_size} failed"
73103
if upload_logs == 1:
74104
log_dir = os.path.dirname(log.logger.handlers[0].baseFilename)
75105
log.info(f"log path:{log_dir}")
@@ -80,6 +110,14 @@ def run(ceph_cluster, **kw):
80110
log.info(f"Disabling debug logs on daemons : {daemon_list}")
81111
if fs_util.disable_logs(client1, daemon_list):
82112
assert False, "Disable logs failed"
113+
if log_parser == 1:
114+
log.info(
115+
f"Parse {log_daemon} dbg logs for expected {expect_list} and unexpected {unexpect_list}"
116+
)
117+
if fs_sys_util.log_parser(
118+
client1, expect_list, unexpect_list, daemon=log_daemon
119+
):
120+
assert False, f"{log_daemon} log parser failed"
83121

84122
log.info("Testcase Results:")
85123
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 = f"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 = f"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)