Asterisk - The Open Source Telephony Project  18.5.0
Functions
refstats Namespace Reference

Functions

def create_stats ()
 
def main (argv=None)
 
def process_file (options)
 
def update_stats (current, peak, total, key, direction, delta)
 

Detailed Description

Process a ref debug log for memory usage

 This will provide information about total and peak
 allocations.

 See http://www.asterisk.org for more information about
 the Asterisk project. Please do not directly contact
 any of the maintainers of this project for assistance;
 the project provides a web site, mailing lists and IRC
 channels for your use.

 This program is free software, distributed under the terms of
 the GNU General Public License Version 2. See the LICENSE file
 at the top of the source tree.

 Copyright (C) 2018, CFWare, LLC
 Corey Farrell <[email protected]>

Function Documentation

◆ create_stats()

def refstats.create_stats ( )
Create statistics object

Definition at line 28 of file refstats.py.

Referenced by process_file().

28 def create_stats():
29  """Create statistics object"""
30  return {
31  'count': 0,
32  'overhead': 0,
33  'user_data': 0,
34  'totalmem': 0
35  }
36 
37 
def create_stats()
Definition: refstats.py:28

◆ main()

def refstats.main (   argv = None)
Main entry point for the script

Definition at line 150 of file refstats.py.

References process_file().

150 def main(argv=None):
151  """Main entry point for the script"""
152 
153  ret_code = 0
154 
155  if argv is None:
156  argv = sys.argv
157 
158  parser = OptionParser()
159 
160  parser.add_option("-f", "--file", action="store", type="string",
161  dest="filepath", default="/var/log/asterisk/refs",
162  help="The full path to the refs file to process")
163 
164  (options, args) = parser.parse_args(argv)
165 
166  if not os.path.isfile(options.filepath):
167  print("File not found: %s" % options.filepath, file=sys.stderr)
168  return -1
169 
170  try:
171  process_file(options)
172  except (KeyboardInterrupt, SystemExit, IOError):
173  print("File processing cancelled", file=sys.stderr)
174  return -1
175 
176  return ret_code
177 
178 
def main(argv=None)
Definition: refstats.py:150
def process_file(options)
Definition: refstats.py:50

◆ process_file()

def refstats.process_file (   options)
The routine that kicks off processing a ref file

Definition at line 50 of file refstats.py.

References create_stats(), len(), and update_stats().

Referenced by main().

50 def process_file(options):
51  """The routine that kicks off processing a ref file"""
52 
53  current = create_stats()
54  total = create_stats()
55  peak = create_stats()
56  object_types = {}
57  objects = {}
58  filename = options.filepath
59 
60  with open(filename, 'r') as ref_file:
61  for line in ref_file:
62  if 'constructor' not in line and 'destructor' not in line:
63  continue
64  # The line format is:
65  # addr,delta,thread_id,file,line,function,state,tag
66  # Only addr, file, line, function, state are used by reflocks.py
67  tokens = line.strip().split(',', 7)
68  addr = tokens[0]
69  state = tokens[6]
70  if 'constructor' in state:
71  split_state = state.split("**")
72  if len(split_state) < 4:
73  print("File does not contain object size information", file=sys.stderr)
74  sys.exit(1)
75 
76  obj_type = '%s:%s:%s' % (tokens[3], tokens[4], tokens[5])
77  if obj_type not in object_types:
78  object_types[obj_type] = {
79  'used': 0,
80  'unused': 0,
81  'none': 0
82  }
83  overhead = int(split_state[2])
84  user_data = int(split_state[3])
85  obj = objects[addr] = {
86  'overhead': overhead,
87  'user_data': user_data,
88  'obj_type': obj_type
89  }
90 
91  direction = 1
92  else:
93  if addr not in objects:
94  # This error would be reported by refcounter.py.
95  continue
96  obj = objects[addr]
97  del objects[addr]
98  direction = -1
99  obj_type = obj['obj_type']
100  if '**lock-state:unused**' in state:
101  object_types[obj_type]['unused'] += 1
102  elif '**lock-state:used**' in state:
103  object_types[obj_type]['used'] += 1
104 
105  # Increment current and peak usage
106  update_stats(current, peak, total, 'count', direction, 1)
107  update_stats(current, peak, total, 'overhead', direction, obj['overhead'])
108  update_stats(current, peak, total, 'user_data', direction, obj['user_data'])
109  update_stats(current, peak, total, 'totalmem', direction, obj['overhead'] + obj['user_data'])
110 
111  print("Total usage statistics:")
112  print("%20s: %d" % ("Count", total['count']))
113  print("%20s: %d" % ("Total Memory (k)", total['totalmem'] / 1024))
114  print("%20s: %d (%.2f%%)" % ("Overhead (k)", total['overhead'] / 1024, total['overhead'] * 100.0 / total['totalmem']))
115  print("%20s: %d" % ("User Data (k)", total['user_data'] / 1024))
116  print("")
117  print("Peak usage statistics:")
118  print("%20s: %d" % ("Count", peak['count']))
119  print("%20s: %d" % ("Total Memory (k)", peak['totalmem'] / 1024))
120  print("%20s: %d (%.2f%%)" % ("Overhead (k)", peak['overhead'] / 1024, peak['overhead'] * 100.0 / peak['totalmem']))
121  print("%20s: %d" % ("User Data (k)", peak['user_data'] / 1024))
122  print("")
123 
124  lockbyobj = {'used': 0, 'total': 0}
125  lockbytype = {'used': 0, 'total': 0}
126  for (allocator, info) in object_types.items():
127  lockbyobj['used'] += info['used']
128  lockbyobj['total'] += info['used'] + info['unused']
129 
130  if info['used'] != 0:
131  lockbytype['used'] += 1
132  elif info['unused'] == 0:
133  # This object type doesn't have locking.
134  continue
135  lockbytype['total'] += 1
136 
137  print("Lock usage statistics:")
138  print("%20s: %d of %d used (%.2f%%)" % (
139  "By object",
140  lockbyobj['used'],
141  lockbyobj['total'],
142  lockbyobj['used'] * 100.0 / lockbyobj['total']))
143  print("%20s: %d of %d used (%.2f%%)" % (
144  "By type",
145  lockbytype['used'],
146  lockbytype['total'],
147  lockbytype['used'] * 100.0 / lockbytype['total']))
148 
149 
def create_stats()
Definition: refstats.py:28
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int update_stats(struct spandsp_pvt *p, int completion_code)
def process_file(options)
Definition: refstats.py:50

◆ update_stats()

def refstats.update_stats (   current,
  peak,
  total,
  key,
  direction,
  delta 
)
Update statistics objects

Definition at line 38 of file refstats.py.

Referenced by process_file().

38 def update_stats(current, peak, total, key, direction, delta):
39  """Update statistics objects"""
40 
41  if direction == 1:
42  total[key] += delta
43 
44  delta *= direction
45  current[key] += delta
46  if current[key] > peak[key]:
47  peak[key] = current[key]
48 
49 
static int update_stats(struct spandsp_pvt *p, int completion_code)