]> git.proxmox.com Git - ceph.git/blame - ceph/src/script/ceph_dump_log.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / script / ceph_dump_log.py
CommitLineData
9f95a23c
TL
1# Copyright (C) 2018 Red Hat Inc.
2#
3# Authors: Sergio Lopez Pascual <slopezpa@redhat.com>
4# Brad Hubbard <bhubbard@redhat.com>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU Library Public License as published by
8# the Free Software Foundation; either version 2, or (at your option)
9# any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Library Public License for more details.
15#
16
17# By default ceph daemons and clients maintain a list of log_max_recent (default
18# 10000) log entries at a high debug level. This script will attempt to dump out
19# that log from a ceph::log::Log* passed to the ceph-dump-log function or, if no
20# object is passed, default to the globally available 'g_ceph_context->_log'
21# (thanks Kefu). This pointer may be obtained via the _log member of a
22# CephContext object (i.e. *cct->_log) from any thread that contains such a
23# CephContext. Normally, you will find a thread waiting in
24# ceph::logging::Log::entry and the 'this' pointer from such a frame can also be
25# passed to ceph-dump-log.
26
27import gdb
28from datetime import datetime
29
30try:
31 # Python 2 forward compatibility
32 range = xrange
33except NameError:
34 pass
35
36class CephDumpLog(gdb.Command):
37 def __init__(self):
38 super(CephDumpLog, self).__init__(
39 'ceph-dump-log',
40 gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, False)
41
42 def invoke(self, args, from_tty):
43 arg_list = gdb.string_to_argv(args)
44 if len(arg_list) < 1:
45 log = gdb.parse_and_eval('g_ceph_context->_log')
46 else:
47 log = gdb.parse_and_eval(arg_list[0])
48
49 luminous_mimic = None
50
51 try:
52 entry = log['m_recent']['m_head']
53 size = log['m_recent']['m_len']
54 luminous_mimic = True
55 except gdb.error:
56 entry = log['m_recent']['m_first']
57 size = log['m_recent']['m_size']
58 end = log['m_recent']['m_end']
59 buff = log['m_recent']['m_buff']
60
61 for i in range(size):
62 if luminous_mimic:
63 try: # early luminous
64 stamp = int(str(entry['m_stamp']['tv']['tv_sec']) + str(entry['m_stamp']['tv']['tv_nsec']))
65 logline = entry['m_streambuf']['m_buf']
66 strlen = int(entry['m_streambuf']['m_buf_len'])
67 except gdb.error: # mimic
68 stamp = entry['m_stamp']['__d']['__r']['count']
69 pptr = entry['m_data']['m_pptr']
70 logline = entry['m_data']['m_buf']
71 strlen = int(pptr - logline)
72 else:
73 stamp = entry['m_stamp']['__d']['__r']['count']
74 logline = entry['str']['m_holder']['m_start']
75 strlen = int(entry['str']['m_holder']['m_size'])
76 thread = entry['m_thread']
77 prio = entry['m_prio']
78 subsys = entry['m_subsys']
79 dt = datetime.fromtimestamp(int(stamp) / 1e9) # Giving up some precision
80 gdb.write(dt.strftime('%Y-%m-%d %H:%M:%S.%f '))
81 gdb.write("thread: {0:#x} priority: {1} subsystem: {2} ".
82 format(int(thread), prio, subsys))
83 gdb.write(logline.string("ascii", errors='ignore')[0:strlen])
84 gdb.write("\n")
85 if luminous_mimic:
86 entry = entry['m_next'].dereference()
87 else:
88 entry = entry + 1
89 if entry >= end:
90 entry = buff
91
92CephDumpLog()