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

Side by Side Diff: infra/services/builder_alerts/__main__.py

Issue 2176403002: Log when leaving main and list remaining threads in builder_alerts (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Fix Created 4 years, 4 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 | infra/services/builder_alerts/alert_builder.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import argparse 6 import argparse
7 import contextlib 7 import contextlib
8 import cStringIO 8 import cStringIO
9 import datetime 9 import datetime
10 import gzip 10 import gzip
11 import json 11 import json
12 import logging 12 import logging
13 import multiprocessing 13 import multiprocessing
14 import os 14 import os
15 import sys 15 import sys
16 import threading
16 import traceback 17 import traceback
17 18
18 import requests 19 import requests
19 import requests_cache 20 import requests_cache
20 21
21 from infra_libs import logs 22 from infra_libs import logs
22 from infra_libs import ts_mon 23 from infra_libs import ts_mon
23 from infra.libs.service_utils import outer_loop 24 from infra.libs.service_utils import outer_loop
24 25
25 from infra.services.builder_alerts import alert_builder 26 from infra.services.builder_alerts import alert_builder
(...skipping 27 matching lines...) Expand all
53 class SubProcess(object): 54 class SubProcess(object):
54 55
55 def __init__(self, cache, old_alerts, builder_filter, jobs): 56 def __init__(self, cache, old_alerts, builder_filter, jobs):
56 super(SubProcess, self).__init__() 57 super(SubProcess, self).__init__()
57 self._cache = cache 58 self._cache = cache
58 self._old_alerts = old_alerts 59 self._old_alerts = old_alerts
59 self._builder_filter = builder_filter 60 self._builder_filter = builder_filter
60 self._jobs = jobs 61 self._jobs = jobs
61 62
62 def __call__(self, master_url): 63 def __call__(self, master_url):
64 logging.debug('Thread for master %s has started', master_url)
63 try: 65 try:
64 master_json = buildbot.fetch_master_json(master_url) 66 master_json = buildbot.fetch_master_json(master_url)
65 if not master_json: 67 if not master_json:
66 return (None, None, None, master_url) 68 return (None, None, None, master_url)
67 69
68 master_alerts, stale_master_alert = alert_builder.alerts_for_master( 70 master_alerts, stale_master_alert = alert_builder.alerts_for_master(
69 self._cache, master_url, master_json, self._old_alerts, 71 self._cache, master_url, master_json, self._old_alerts,
70 self._builder_filter, self._jobs) 72 self._builder_filter, self._jobs)
71 73
72 # FIXME: The builder info doesn't really belong here. The builder 74 # FIXME: The builder info doesn't really belong here. The builder
73 # revisions tool uses this and we happen to have the builder json cached 75 # revisions tool uses this and we happen to have the builder json cached
74 # at this point so it's cheap to compute, but it should be moved 76 # at this point so it's cheap to compute, but it should be moved
75 # to a different feed. 77 # to a different feed.
76 data, stale_builder_alerts = ( 78 data, stale_builder_alerts = (
77 buildbot.latest_builder_info_and_alerts_for_master( 79 buildbot.latest_builder_info_and_alerts_for_master(
78 self._cache, master_url, master_json)) 80 self._cache, master_url, master_json))
79 if stale_master_alert: 81 if stale_master_alert:
80 stale_builder_alerts.append(stale_master_alert) 82 stale_builder_alerts.append(stale_master_alert)
81 return (master_alerts, data, stale_builder_alerts, master_url) 83 return (master_alerts, data, stale_builder_alerts, master_url)
82 except: 84 except:
83 # Put all exception text into an exception and raise that so it doesn't 85 # Put all exception text into an exception and raise that so it doesn't
84 # get eaten by the multiprocessing code. 86 # get eaten by the multiprocessing code.
85 msg = '%s for master url %s' % ( 87 msg = '%s for master url %s' % (
86 ''.join(traceback.format_exception(*sys.exc_info())), 88 ''.join(traceback.format_exception(*sys.exc_info())),
87 master_url, 89 master_url,
88 ) 90 )
89 raise Exception(msg) 91 raise Exception(msg)
92 finally:
93 logging.debug('Thread for master %s has finished', master_url)
90 94
91 95
92 def query_findit(findit_api_url, alerts): 96 def query_findit(findit_api_url, alerts):
93 """Get analysis results from Findit for failures in the given alerts. 97 """Get analysis results from Findit for failures in the given alerts.
94 98
95 Args: 99 Args:
96 findit_api_url (str): The URL to findit's api for build failure analysis. 100 findit_api_url (str): The URL to findit's api for build failure analysis.
97 alerts (list): A non-empty list of failure alerts. 101 alerts (list): A non-empty list of failure alerts.
98 102
99 Returns: 103 Returns:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 186
183 187
184 def gzipped(data): 188 def gzipped(data):
185 s = cStringIO.StringIO() 189 s = cStringIO.StringIO()
186 with contextlib.closing(gzip.GzipFile(fileobj=s, mode='w')) as g: 190 with contextlib.closing(gzip.GzipFile(fileobj=s, mode='w')) as g:
187 g.write(data) 191 g.write(data)
188 return s.getvalue() 192 return s.getvalue()
189 193
190 194
191 def inner_loop(args): 195 def inner_loop(args):
196 logging.debug('Starting inner loop')
192 old_api_endpoint = string_helpers.slash_join(args.api_endpoint_prefix, 197 old_api_endpoint = string_helpers.slash_join(args.api_endpoint_prefix,
193 args.old_api_path) if args.old_api_path else None 198 args.old_api_path) if args.old_api_path else None
194 if not old_api_endpoint: 199 if not old_api_endpoint:
195 logging.warn( 200 logging.warn(
196 'No /data url passed, will write to builder_alerts.json. JSON posted ' 201 'No /data url passed, will write to builder_alerts.json. JSON posted '
197 'to new API endpoints will be written to builder_alerts_<tree>.json ' 202 'to new API endpoints will be written to builder_alerts_<tree>.json '
198 'files.') 203 'files.')
199 204
200 if args.use_cache: 205 if args.use_cache:
201 requests_cache.install_cache('failure_stats') 206 requests_cache.install_cache('failure_stats')
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 ' %s' % (master, builder, step, reason)) 247 ' %s' % (master, builder, step, reason))
243 248
244 old_alerts[alert_key] = alert 249 old_alerts[alert_key] = alert
245 250
246 latest_builder_info = {} 251 latest_builder_info = {}
247 stale_builder_alerts = [] 252 stale_builder_alerts = []
248 missing_masters = [] 253 missing_masters = []
249 alerts = [] 254 alerts = []
250 suspected_cls = [] 255 suspected_cls = []
251 256
257 logging.debug('Processing all masters via process pool')
252 pool = multiprocessing.Pool(processes=args.processes) 258 pool = multiprocessing.Pool(processes=args.processes)
253 master_datas = pool.map(SubProcess(cache, old_alerts, args.builder_filter, 259 master_datas = pool.map(SubProcess(cache, old_alerts, args.builder_filter,
254 args.jobs), master_urls) 260 args.jobs), master_urls)
261 logging.debug('Closing all threads in master process pool')
255 pool.close() 262 pool.close()
256 pool.join() 263 pool.join()
264 logging.debug('Joined all threads in master process pool')
257 265
258 for data in master_datas: 266 for data in master_datas:
259 # TODO(ojan): We should put an alert in the JSON for this master so 267 # TODO(ojan): We should put an alert in the JSON for this master so
260 # we can show that the master is down in the sheriff-o-matic UI. 268 # we can show that the master is down in the sheriff-o-matic UI.
261 if not data[0]: 269 if not data[0]:
262 missing_masters.extend([data[3]]) 270 missing_masters.extend([data[3]])
263 continue 271 continue
264 alerts.extend(data[0]) 272 alerts.extend(data[0])
265 latest_builder_info.update(data[1]) 273 latest_builder_info.update(data[1])
266 stale_builder_alerts.extend(data[2]) 274 stale_builder_alerts.extend(data[2])
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 resp.status_code, resp.reason, resp.content) 345 resp.status_code, resp.reason, resp.content)
338 ret = False 346 ret = False
339 else: 347 else:
340 with open('builder_alerts_%s.json' % tree, 'w') as f: 348 with open('builder_alerts_%s.json' % tree, 'w') as f:
341 f.write(json.dumps(json_data, indent=1)) 349 f.write(json.dumps(json_data, indent=1))
342 else: 350 else:
343 logging.error( 351 logging.error(
344 '--crbug-service-account was not specified, can not get crbug issues') 352 '--crbug-service-account was not specified, can not get crbug issues')
345 ret = False 353 ret = False
346 354
355 logging.debug('Returning from inner loop')
347 return ret 356 return ret
348 357
349 358
350 def main(args): 359 def main(args):
351 parser = argparse.ArgumentParser(prog='run.py %s' % __package__) 360 parser = argparse.ArgumentParser(prog='run.py %s' % __package__)
352 parser.add_argument('data_url', action='store', nargs='*') # Deprecated 361 parser.add_argument('data_url', action='store', nargs='*') # Deprecated
353 parser.add_argument('--use-cache', action='store_true') 362 parser.add_argument('--use-cache', action='store_true')
354 parser.add_argument('--master-filter', action='store') 363 parser.add_argument('--master-filter', action='store')
355 parser.add_argument('--builder-filter', action='store') 364 parser.add_argument('--builder-filter', action='store')
356 parser.add_argument('--processes', default=PARALLEL_TASKS, action='store', 365 parser.add_argument('--processes', default=PARALLEL_TASKS, action='store',
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 def filter(record): 430 def filter(record):
422 if record.levelno == logging.INFO: 431 if record.levelno == logging.INFO:
423 return False 432 return False
424 return True 433 return True
425 logging.getLogger('requests.packages.urllib3.connectionpool').addFilter( 434 logging.getLogger('requests.packages.urllib3.connectionpool').addFilter(
426 _ConnectionpoolFilter()) 435 _ConnectionpoolFilter())
427 436
428 def outer_loop_iteration(): 437 def outer_loop_iteration():
429 return inner_loop(args) 438 return inner_loop(args)
430 439
440 logging.debug('Starting outer loop')
431 loop_results = outer_loop.loop( 441 loop_results = outer_loop.loop(
432 task=outer_loop_iteration, 442 task=outer_loop_iteration,
433 sleep_timeout=lambda: 5, 443 sleep_timeout=lambda: 5,
434 **loop_args) 444 **loop_args)
445 logging.debug('Finished outer loop')
435 446
436 logging.debug('Flushing ts_mon starting') 447 logging.debug('Flushing ts_mon starting')
437 ts_mon.flush() 448 ts_mon.flush()
438 logging.debug('Flushing ts_mon completed') 449 logging.debug('Flushing ts_mon completed')
439 return 0 if loop_results.success else 1 450 return 0 if loop_results.success else 1
440 451
441 452
442 if __name__ == '__main__': 453 if __name__ == '__main__':
454 logging.debug('Started main')
443 sys.exit(main(sys.argv[1:])) 455 sys.exit(main(sys.argv[1:]))
456 current_thread_descriptions = [t.name + (' (daemon)' if t.isDaemon() else '')
tandrii(chromium) 2016/07/26 09:56:35 this will never be executed. sys.exit raises Syste
457 for t in threading.enumerate()]
458 logging.debug(
459 'Leaving main. Threads: %s', ', '.join(current_thread_descriptions))
OLDNEW
« no previous file with comments | « no previous file | infra/services/builder_alerts/alert_builder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698