exception-tracker: enable send email on exception
This commit is contained in:
parent
6a0c148cae
commit
d0a117b4ad
7 changed files with 113 additions and 2 deletions
|
|
@ -350,6 +350,17 @@ labs_settings_active = true
|
|||
; This is used to store exception from RhodeCode in shared directory
|
||||
#exception_tracker.store_path =
|
||||
|
||||
; Send email with exception details when it happens
|
||||
#exception_tracker.send_email = false
|
||||
|
||||
; Comma separated list of recipients for exception emails,
|
||||
; e.g admin@rhodecode.com,devops@rhodecode.com
|
||||
; Can be left empty, then emails will be sent to ALL super-admins
|
||||
#exception_tracker.send_email_recipients =
|
||||
|
||||
; optional prefix to Add to email Subject
|
||||
#exception_tracker.email_prefix = [RHODECODE ERROR]
|
||||
|
||||
; File store configuration. This is used to store and serve uploaded files
|
||||
file_store.enabled = true
|
||||
|
||||
|
|
|
|||
|
|
@ -301,6 +301,17 @@ labs_settings_active = true
|
|||
; This is used to store exception from RhodeCode in shared directory
|
||||
#exception_tracker.store_path =
|
||||
|
||||
; Send email with exception details when it happens
|
||||
#exception_tracker.send_email = false
|
||||
|
||||
; Comma separated list of recipients for exception emails,
|
||||
; e.g admin@rhodecode.com,devops@rhodecode.com
|
||||
; Can be left empty, then emails will be sent to ALL super-admins
|
||||
#exception_tracker.send_email_recipients =
|
||||
|
||||
; optional prefix to Add to email Subject
|
||||
#exception_tracker.email_prefix = [RHODECODE ERROR]
|
||||
|
||||
; File store configuration. This is used to store and serve uploaded files
|
||||
file_store.enabled = true
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,15 @@ Check if we should use full-topic or mini-topic.
|
|||
'modified': ['b/modified_file.rst'],
|
||||
'removed': ['.idea'],
|
||||
})
|
||||
|
||||
exc_traceback = {
|
||||
'exc_utc_date': '2020-03-26T12:54:50.683281',
|
||||
'exc_id': 139638856342656,
|
||||
'exc_timestamp': '1585227290.683288',
|
||||
'version': 'v1',
|
||||
'exc_message': 'Traceback (most recent call last):\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/tweens.py", line 41, in excview_tween\n response = handler(request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/router.py", line 148, in handle_request\n registry, request, context, context_iface, view_name\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/view.py", line 667, in _call_view\n response = view_callable(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 188, in attr_view\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 214, in predicate_wrapper\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 401, in viewresult_to_response\n result = view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 132, in _class_view\n response = getattr(inst, attr)()\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/apps/debug_style/views.py", line 355, in render_email\n template_type, **email_kwargs.get(email_id, {}))\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/model/notification.py", line 402, in render_email\n body = email_template.render(None, **_kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 95, in render\n return self._render_with_exc(tmpl, args, kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 79, in _render_with_exc\n return render_func.render(*args, **kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/template.py", line 476, in render\n return runtime._render(self, self.callable_, args, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 883, in _render\n **_kwargs_for_callable(callable_, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 920, in _render_context\n _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 947, in _exec_template\n callable_(context, *args, **kwargs)\n File "rhodecode_templates_email_templates_base_mako", line 63, in render_body\n File "rhodecode_templates_email_templates_exception_tracker_mako", line 43, in render_body\nAttributeError: \'str\' object has no attribute \'get\'\n',
|
||||
'exc_type': 'AttributeError'
|
||||
}
|
||||
email_kwargs = {
|
||||
'test': {},
|
||||
'message': {
|
||||
|
|
@ -97,6 +106,13 @@ Check if we should use full-topic or mini-topic.
|
|||
'user': user,
|
||||
'date': datetime.datetime.now(),
|
||||
},
|
||||
'exception': {
|
||||
'email_prefix': '[RHODECODE ERROR]',
|
||||
'exc_id': exc_traceback['exc_id'],
|
||||
'exc_url': 'http://server-url/{}'.format(exc_traceback['exc_id']),
|
||||
'exc_type_name': 'NameError',
|
||||
'exc_traceback': exc_traceback,
|
||||
},
|
||||
'password_reset': {
|
||||
'password_reset_url': 'http://example.com/reset-rhodecode-password/token',
|
||||
|
||||
|
|
|
|||
|
|
@ -611,6 +611,14 @@ def _sanitize_cache_settings(settings):
|
|||
settings,
|
||||
'exception_tracker.store_path',
|
||||
temp_store, lower=False, default_when_empty=True)
|
||||
_bool_setting(
|
||||
settings,
|
||||
'exception_tracker.send_email',
|
||||
'false')
|
||||
_string_setting(
|
||||
settings,
|
||||
'exception_tracker.email_prefix',
|
||||
'[RHODECODE ERROR]', lower=False, default_when_empty=True)
|
||||
|
||||
# cache_perms
|
||||
_string_setting(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import traceback
|
|||
import tempfile
|
||||
import glob
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# NOTE: Any changes should be synced with exc_tracking at vcsserver.lib.exc_tracking
|
||||
|
|
@ -77,10 +76,11 @@ def get_exc_store():
|
|||
return _exc_store_path
|
||||
|
||||
|
||||
def _store_exception(exc_id, exc_type_name, exc_traceback, prefix):
|
||||
def _store_exception(exc_id, exc_type_name, exc_traceback, prefix, send_email=None):
|
||||
"""
|
||||
Low level function to store exception in the exception tracker
|
||||
"""
|
||||
import rhodecode as app
|
||||
|
||||
exc_store_path = get_exc_store()
|
||||
exc_data, org_data = exc_serialize(exc_id, exc_traceback, exc_type_name)
|
||||
|
|
@ -92,6 +92,50 @@ def _store_exception(exc_id, exc_type_name, exc_traceback, prefix):
|
|||
f.write(exc_data)
|
||||
log.debug('Stored generated exception %s as: %s', exc_id, stored_exc_path)
|
||||
|
||||
if send_email is None:
|
||||
# NOTE(marcink): read app config unless we specify explicitly
|
||||
send_email = app.CONFIG.get('exception_tracker.send_email', False)
|
||||
|
||||
if send_email:
|
||||
try:
|
||||
send_exc_email(exc_id, exc_type_name)
|
||||
except Exception:
|
||||
log.exception('Failed to send exception email')
|
||||
pass
|
||||
|
||||
|
||||
def send_exc_email(exc_id, exc_type_name):
|
||||
import rhodecode as app
|
||||
from pyramid.threadlocal import get_current_request
|
||||
from rhodecode.apps._base import TemplateArgs
|
||||
from rhodecode.lib.utils2 import aslist
|
||||
from rhodecode.lib.celerylib import run_task, tasks
|
||||
from rhodecode.lib.base import attach_context_attributes
|
||||
from rhodecode.model.notification import EmailNotificationModel
|
||||
|
||||
request = get_current_request()
|
||||
|
||||
recipients = aslist(app.CONFIG.get('exception_tracker.send_email_recipients', ''))
|
||||
log.debug('Sending Email exception to: `%s`', recipients or 'all super admins')
|
||||
|
||||
# NOTE(marcink): needed for email template rendering
|
||||
attach_context_attributes(TemplateArgs(), request, request.user.user_id)
|
||||
|
||||
email_kwargs = {
|
||||
'email_prefix': app.CONFIG.get('exception_tracker.email_prefix', '') or '[RHODECODE ERROR]',
|
||||
'exc_url': request.route_url('admin_settings_exception_tracker_show', exception_id=exc_id),
|
||||
'exc_id': exc_id,
|
||||
'exc_type_name': exc_type_name,
|
||||
'exc_traceback': read_exception(exc_id, prefix=None),
|
||||
}
|
||||
|
||||
(subject, headers, email_body,
|
||||
email_body_plaintext) = EmailNotificationModel().render_email(
|
||||
EmailNotificationModel.TYPE_EMAIL_EXCEPTION, **email_kwargs)
|
||||
|
||||
run_task(tasks.send_email, recipients, subject,
|
||||
email_body_plaintext, email_body)
|
||||
|
||||
|
||||
def _prepare_exception(exc_info):
|
||||
exc_type, exc_value, exc_traceback = exc_info
|
||||
|
|
|
|||
|
|
@ -304,6 +304,7 @@ class EmailNotificationModel(BaseModel):
|
|||
TYPE_PASSWORD_RESET = 'password_reset'
|
||||
TYPE_PASSWORD_RESET_CONFIRMATION = 'password_reset_confirmation'
|
||||
TYPE_EMAIL_TEST = 'email_test'
|
||||
TYPE_EMAIL_EXCEPTION = 'exception'
|
||||
TYPE_TEST = 'test'
|
||||
|
||||
email_types = {
|
||||
|
|
@ -311,6 +312,8 @@ class EmailNotificationModel(BaseModel):
|
|||
'rhodecode:templates/email_templates/main.mako',
|
||||
TYPE_TEST:
|
||||
'rhodecode:templates/email_templates/test.mako',
|
||||
TYPE_EMAIL_EXCEPTION:
|
||||
'rhodecode:templates/email_templates/exception_tracker.mako',
|
||||
TYPE_EMAIL_TEST:
|
||||
'rhodecode:templates/email_templates/email_test.mako',
|
||||
TYPE_REGISTRATION:
|
||||
|
|
|
|||
18
rhodecode/templates/email_templates/exception_tracker.mako
Normal file
18
rhodecode/templates/email_templates/exception_tracker.mako
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="base.mako"/>
|
||||
<%namespace name="base" file="base.mako"/>
|
||||
|
||||
<%def name="subject()" filter="n,trim,whitespace_filter">
|
||||
${email_prefix} ${exc_type_name} (${exc_id})
|
||||
</%def>
|
||||
|
||||
## plain text version of the email. Empty by default
|
||||
<%def name="body_plaintext()" filter="n,trim">
|
||||
NO PLAINTEXT VERSION
|
||||
</%def>
|
||||
|
||||
<h4>${_('Exception `{}` generated on UTC date: {}').format(exc_traceback.get('exc_type', 'NO_TYPE'), exc_traceback.get('exc_utc_date', 'NO_DATE'))}</h4>
|
||||
<p>
|
||||
View exception <a href="${exc_url}">${exc_id}</a>
|
||||
</p>
|
||||
<pre>${exc_traceback.get('exc_message', 'NO_MESSAGE')}</pre>
|
||||
Loading…
Add table
Add a link
Reference in a new issue