| OLD | NEW |
| 1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2009 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 """Breakpad for Python. | 5 """Breakpad for Python. |
| 6 | 6 |
| 7 Sends a notification when a process stops on an exception. | 7 Sends a notification when a process stops on an exception. |
| 8 | 8 |
| 9 It is only enabled when all these conditions are met: | 9 It is only enabled when all these conditions are met: |
| 10 1. hostname finishes with '.google.com' | 10 1. hostname finishes with '.google.com' or 'chromium.org' |
| 11 2. main module name doesn't contain the word 'test' | 11 2. main module name doesn't contain the word 'test' |
| 12 3. no NO_BREAKPAD environment variable is defined | 12 3. no NO_BREAKPAD environment variable is defined |
| 13 """ | 13 """ |
| 14 | 14 |
| 15 import atexit | 15 import atexit |
| 16 import getpass | 16 import getpass |
| 17 import os | 17 import os |
| 18 import socket | 18 import socket |
| 19 import sys | 19 import sys |
| 20 import time | 20 import time |
| 21 import traceback | 21 import traceback |
| 22 import urllib | 22 import urllib |
| 23 import urllib2 | 23 import urllib2 |
| 24 | 24 |
| 25 | 25 |
| 26 # Configure these values. | 26 # Configure these values. |
| 27 DEFAULT_URL = 'https://chromium-status.appspot.com' | 27 DEFAULT_URL = 'https://chromium-status.appspot.com' |
| 28 | 28 |
| 29 # Global variable to prevent double registration. |
| 29 _REGISTERED = False | 30 _REGISTERED = False |
| 30 | 31 |
| 31 _TIME_STARTED = time.time() | 32 _TIME_STARTED = time.time() |
| 32 | 33 |
| 34 _HOST_NAME = socket.getfqdn() |
| 35 |
| 33 | 36 |
| 34 def post(url, params): | 37 def post(url, params): |
| 35 """HTTP POST with timeout when it's supported.""" | 38 """HTTP POST with timeout when it's supported.""" |
| 36 kwargs = {} | 39 kwargs = {} |
| 37 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 26: | 40 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 26: |
| 38 kwargs['timeout'] = 4 | 41 kwargs['timeout'] = 4 |
| 39 request = urllib2.urlopen(url, urllib.urlencode(params), **kwargs) | 42 request = urllib2.urlopen(url, urllib.urlencode(params), **kwargs) |
| 40 out = request.read() | 43 out = request.read() |
| 41 request.close() | 44 request.close() |
| 42 return out | 45 return out |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 """Sends the stack trace to the breakpad server.""" | 77 """Sends the stack trace to the breakpad server.""" |
| 75 if not url: | 78 if not url: |
| 76 url = DEFAULT_URL + '/breakpad' | 79 url = DEFAULT_URL + '/breakpad' |
| 77 print 'Sending crash report ...' | 80 print 'Sending crash report ...' |
| 78 try: | 81 try: |
| 79 params = { | 82 params = { |
| 80 'args': sys.argv, | 83 'args': sys.argv, |
| 81 'stack': stack[0:4096], | 84 'stack': stack[0:4096], |
| 82 'user': getpass.getuser(), | 85 'user': getpass.getuser(), |
| 83 'exception': FormatException(last_tb), | 86 'exception': FormatException(last_tb), |
| 84 'host': socket.getfqdn(), | 87 'host': _HOST_NAME, |
| 85 'cwd': os.getcwd(), | 88 'cwd': os.getcwd(), |
| 86 'version': sys.version, | 89 'version': sys.version, |
| 87 } | 90 } |
| 88 # pylint: disable=W0702 | 91 # pylint: disable=W0702 |
| 89 print('\n'.join(' %s: %s' % (k, v[0:maxlen]) | 92 print('\n'.join(' %s: %s' % (k, v[0:maxlen]) |
| 90 for k, v in params.iteritems())) | 93 for k, v in params.iteritems())) |
| 91 print(post(url, params)) | 94 print(post(url, params)) |
| 92 except IOError: | 95 except IOError: |
| 93 print('There was a failure while trying to send the stack trace. Too bad.') | 96 print('There was a failure while trying to send the stack trace. Too bad.') |
| 94 | 97 |
| 95 | 98 |
| 96 def SendProfiling(url=None): | 99 def SendProfiling(url=None): |
| 97 try: | 100 try: |
| 98 if not url: | 101 if not url: |
| 99 url = DEFAULT_URL + '/profiling' | 102 url = DEFAULT_URL + '/profiling' |
| 100 params = { | 103 params = { |
| 101 'argv': ' '.join(sys.argv), | 104 'argv': ' '.join(sys.argv), |
| 105 # Strip the hostname. |
| 106 'domain': _HOST_NAME.split('.', 1)[-1], |
| 102 'duration': time.time() - _TIME_STARTED, | 107 'duration': time.time() - _TIME_STARTED, |
| 103 'platform': sys.platform, | 108 'platform': sys.platform, |
| 104 } | 109 } |
| 105 post(url, params) | 110 post(url, params) |
| 106 except IOError: | 111 except IOError: |
| 107 pass | 112 pass |
| 108 | 113 |
| 109 | 114 |
| 110 def CheckForException(): | 115 def CheckForException(): |
| 111 """Runs at exit. Look if there was an exception active.""" | 116 """Runs at exit. Look if there was an exception active.""" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 124 global _REGISTERED | 129 global _REGISTERED |
| 125 if _REGISTERED: | 130 if _REGISTERED: |
| 126 return | 131 return |
| 127 _REGISTERED = True | 132 _REGISTERED = True |
| 128 atexit.register(CheckForException) | 133 atexit.register(CheckForException) |
| 129 | 134 |
| 130 | 135 |
| 131 # Skip unit tests and we don't want anything from non-googler. | 136 # Skip unit tests and we don't want anything from non-googler. |
| 132 if (not 'test' in sys.modules['__main__'].__file__ and | 137 if (not 'test' in sys.modules['__main__'].__file__ and |
| 133 not 'NO_BREAKPAD' in os.environ and | 138 not 'NO_BREAKPAD' in os.environ and |
| 134 (socket.getfqdn().endswith('.google.com') or | 139 (_HOST_NAME.endswith('.google.com') or |
| 135 socket.getfqdn().endswith('.chromium.org'))): | 140 _HOST_NAME.endswith('.chromium.org'))): |
| 136 Register() | 141 Register() |
| 137 | 142 |
| 138 # Uncomment this line if you want to test it out. | 143 # Uncomment this line if you want to test it out. |
| 139 #Register() | 144 #Register() |
| OLD | NEW |