Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: tools/metrics/histograms/extract_histograms.py

Issue 2426473006: Add support for base histograms in histograms.xml. (Closed)
Patch Set: update syntax Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Extract histogram names from the description XML file. 5 """Extract histogram names from the description XML file.
6 6
7 For more information on the format of the XML file, which is self-documenting, 7 For more information on the format of the XML file, which is self-documenting,
8 see histograms.xml; however, here is a simple example to get you started. The 8 see histograms.xml; however, here is a simple example to get you started. The
9 XML below will generate the following five histograms: 9 XML below will generate the following five histograms:
10 10
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 56
57 import copy 57 import copy
58 import logging 58 import logging
59 import xml.dom.minidom 59 import xml.dom.minidom
60 60
61 OWNER_FIELD_PLACEHOLDER = ( 61 OWNER_FIELD_PLACEHOLDER = (
62 'Please list the metric\'s owners. Add more owner tags as needed.') 62 'Please list the metric\'s owners. Add more owner tags as needed.')
63 63
64 MAX_HISTOGRAM_SUFFIX_DEPENDENCY_DEPTH = 5 64 MAX_HISTOGRAM_SUFFIX_DEPENDENCY_DEPTH = 5
65 65
66 DEFAULT_BASE_HISTOGRAM_OBSOLETE_REASON = (
67 'Base histogram. Use suffixes of this histogram instead.')
68
66 69
67 class Error(Exception): 70 class Error(Exception):
68 pass 71 pass
69 72
70 73
71 def _JoinChildNodes(tag): 74 def _JoinChildNodes(tag):
72 """Join child nodes into a single text. 75 """Join child nodes into a single text.
73 76
74 Applicable to leafs like 'summary' and 'detail'. 77 Applicable to leafs like 'summary' and 'detail'.
75 78
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 def _ExtractOwners(xml_node): 226 def _ExtractOwners(xml_node):
224 """Extract all owners into a list from owner tag under |xml_node|.""" 227 """Extract all owners into a list from owner tag under |xml_node|."""
225 owners = [] 228 owners = []
226 for owner_node in xml_node.getElementsByTagName('owner'): 229 for owner_node in xml_node.getElementsByTagName('owner'):
227 owner_entry = _NormalizeString(_JoinChildNodes(owner_node)) 230 owner_entry = _NormalizeString(_JoinChildNodes(owner_node))
228 if OWNER_FIELD_PLACEHOLDER not in owner_entry: 231 if OWNER_FIELD_PLACEHOLDER not in owner_entry:
229 owners.append(owner_entry) 232 owners.append(owner_entry)
230 return owners 233 return owners
231 234
232 235
236 def _ProcessBaseHistogramAttribute(node, histogram_entry):
237 if node.hasAttribute('base'):
238 is_base = node.getAttribute('base').lower() == 'true'
239 histogram_entry['base'] = is_base
240 if is_base and 'obsolete' not in histogram_entry:
241 histogram_entry['obsolete'] = DEFAULT_BASE_HISTOGRAM_OBSOLETE_REASON
242
243
233 def _ExtractHistogramsFromXmlTree(tree, enums): 244 def _ExtractHistogramsFromXmlTree(tree, enums):
234 """Extract all <histogram> nodes in the tree into a dictionary.""" 245 """Extract all <histogram> nodes in the tree into a dictionary."""
235 246
236 # Process the histograms. The descriptions can include HTML tags. 247 # Process the histograms. The descriptions can include HTML tags.
237 histograms = {} 248 histograms = {}
238 have_errors = False 249 have_errors = False
239 last_name = None 250 last_name = None
240 for histogram in tree.getElementsByTagName('histogram'): 251 for histogram in tree.getElementsByTagName('histogram'):
241 name = histogram.getAttribute('name') 252 name = histogram.getAttribute('name')
242 if last_name is not None and name.lower() < last_name.lower(): 253 if last_name is not None and name.lower() < last_name.lower():
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 292
282 # Handle enum types. 293 # Handle enum types.
283 if histogram.hasAttribute('enum'): 294 if histogram.hasAttribute('enum'):
284 enum_name = histogram.getAttribute('enum') 295 enum_name = histogram.getAttribute('enum')
285 if enum_name not in enums: 296 if enum_name not in enums:
286 logging.error('Unknown enum %s in histogram %s', enum_name, name) 297 logging.error('Unknown enum %s in histogram %s', enum_name, name)
287 have_errors = True 298 have_errors = True
288 else: 299 else:
289 histogram_entry['enum'] = enums[enum_name] 300 histogram_entry['enum'] = enums[enum_name]
290 301
302 _ProcessBaseHistogramAttribute(histogram, histogram_entry)
303
291 return histograms, have_errors 304 return histograms, have_errors
292 305
293 306
294 # Finds an <obsolete> node amongst |node|'s immediate children and returns its 307 # Finds an <obsolete> node amongst |node|'s immediate children and returns its
295 # content as a string. Returns None if no such node exists. 308 # content as a string. Returns None if no such node exists.
296 def _GetObsoleteReason(node): 309 def _GetObsoleteReason(node):
297 for child in node.childNodes: 310 for child in node.childNodes:
298 if child.localName == 'obsolete': 311 if child.localName == 'obsolete':
299 # There can be at most 1 obsolete element per node. 312 # There can be at most 1 obsolete element per node.
300 return _JoinChildNodes(child) 313 return _JoinChildNodes(child)
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 if with_suffixes: 404 if with_suffixes:
392 suffixes_to_add = with_suffixes 405 suffixes_to_add = with_suffixes
393 else: 406 else:
394 suffixes_to_add = suffix_nodes 407 suffixes_to_add = suffix_nodes
395 for suffix in suffixes_to_add: 408 for suffix in suffixes_to_add:
396 suffix_name = suffix.getAttribute('name') 409 suffix_name = suffix.getAttribute('name')
397 try: 410 try:
398 new_histogram_name = _ExpandHistogramNameWithSuffixes( 411 new_histogram_name = _ExpandHistogramNameWithSuffixes(
399 suffix_name, histogram_name, histogram_suffixes) 412 suffix_name, histogram_name, histogram_suffixes)
400 if new_histogram_name != histogram_name: 413 if new_histogram_name != histogram_name:
401 histograms[new_histogram_name] = copy.deepcopy( 414 new_histogram = copy.deepcopy(histograms[histogram_name])
402 histograms[histogram_name]) 415 # Do not copy forward base histogram state to suffixed
416 # histograms. Any suffixed histograms that wish to remain base
417 # histogram must explicitly declare themselves as base histograms.
Ilya Sherman 2016/10/18 21:05:58 nit: s/histogram/histograms
Bryan McQuade 2016/10/18 23:15:19 done, thanks!
418 if new_histogram.get('base', False):
419 del new_histogram['base']
420 if (new_histogram.get('obsolete', '') ==
421 DEFAULT_BASE_HISTOGRAM_OBSOLETE_REASON):
422 del new_histogram['obsolete']
423 histograms[new_histogram_name] = new_histogram
403 424
404 suffix_label = suffix_labels.get(suffix_name, '') 425 suffix_label = suffix_labels.get(suffix_name, '')
405 426
406 # TODO(yiyaoliu): Rename these to be consistent with the new naming. 427 # TODO(yiyaoliu): Rename these to be consistent with the new naming.
407 # It is kept unchanged for now to be it's used by dashboards. 428 # It is kept unchanged for now to be it's used by dashboards.
408 if 'fieldtrial_groups' not in histograms[new_histogram_name]: 429 if 'fieldtrial_groups' not in histograms[new_histogram_name]:
409 histograms[new_histogram_name]['fieldtrial_groups'] = [] 430 histograms[new_histogram_name]['fieldtrial_groups'] = []
410 histograms[new_histogram_name]['fieldtrial_groups'].append( 431 histograms[new_histogram_name]['fieldtrial_groups'].append(
411 suffix_name) 432 suffix_name)
412 433
(...skipping 16 matching lines...) Expand all
429 # group itself was obsolete as well. 450 # group itself was obsolete as well.
430 obsolete_reason = _GetObsoleteReason(suffix) 451 obsolete_reason = _GetObsoleteReason(suffix)
431 if not obsolete_reason: 452 if not obsolete_reason:
432 obsolete_reason = group_obsolete_reason 453 obsolete_reason = group_obsolete_reason
433 454
434 # If the suffix has an obsolete tag, all histograms it generates 455 # If the suffix has an obsolete tag, all histograms it generates
435 # inherit it. 456 # inherit it.
436 if obsolete_reason: 457 if obsolete_reason:
437 histograms[new_histogram_name]['obsolete'] = obsolete_reason 458 histograms[new_histogram_name]['obsolete'] = obsolete_reason
438 459
460 _ProcessBaseHistogramAttribute(suffix, histograms[new_histogram_name])
461
439 except Error: 462 except Error:
440 have_errors = True 463 have_errors = True
441 464
442 return have_errors 465 return have_errors
443 466
444 467
445 def ExtractHistogramsFromFile(file_handle): 468 def ExtractHistogramsFromFile(file_handle):
446 """Compute the histogram names and descriptions from the XML representation. 469 """Compute the histogram names and descriptions from the XML representation.
447 470
448 Args: 471 Args:
(...skipping 29 matching lines...) Expand all
478 with open(filename, 'r') as f: 501 with open(filename, 'r') as f:
479 histograms, had_errors = ExtractHistogramsFromFile(f) 502 histograms, had_errors = ExtractHistogramsFromFile(f)
480 if had_errors: 503 if had_errors:
481 logging.error('Error parsing %s', filename) 504 logging.error('Error parsing %s', filename)
482 raise Error() 505 raise Error()
483 return histograms 506 return histograms
484 507
485 508
486 def ExtractNames(histograms): 509 def ExtractNames(histograms):
487 return sorted(histograms.keys()) 510 return sorted(histograms.keys())
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698