@@ -25,6 +25,7 @@ def __init__(self, ceph_cluster):
25
25
Args:
26
26
ceph_cluster (ceph.ceph.Ceph): ceph cluster
27
27
"""
28
+ self .ceph_cluster = ceph_cluster
28
29
self .mons = ceph_cluster .get_ceph_objects ("mon" )
29
30
self .mgrs = ceph_cluster .get_ceph_objects ("mgr" )
30
31
self .mdss = ceph_cluster .get_ceph_objects ("mds" )
@@ -273,3 +274,99 @@ def wait_for_two_active_mds(
273
274
time .sleep (retry_interval ) # Retry after the specified interval
274
275
275
276
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