def send_email_notifications(event_id): """ Send email notifications of events. :param event_id: event ID :type event_id: int """ from cupola.api.run import create_api from cupola.web import create_app with create_api().app_context() as ctx: if not event_id: ctx.app.logger.warning("No event ID") return event = Event.query.get(event_id) if not event: ctx.app.logger.warning("No event with ID {}".format(event_id)) return group = EventGroup.query.filter_by(message=event.message).first() subject = "Event registered for project {}".format(group.project.name) # We use `create_app` here so the event URLs are calculated properly # FIXME: There has to be a nicer way to do this. with create_app().app_context(): event_url = url_for("events.view_event", event_id=event.event_id, _external=True) if group.project.email_notifications: with mail.connect() as conn: for user in group.project.email_notifications: msg = Message(subject, recipients=[user.email]) msg.body = render_template("api/event.txt", user=user, group=group, event_url=event_url) msg.html = render_template("api/event.html", user=user, group=group, event_url=event_url) conn.send(msg)
def record_data(project_id, data): """ Record sentry data. :param project_id: Project ID to dump data against. :type project_id: int :param data: data sent from the client :type data: dict :return: event ID :rtype: int """ from cupola.api.run import create_api if project_id != data.pop("project"): return with create_api().app_context(): project = Project.query.get(project_id) if not project: return # We do this processing after checking if the project exists # to possibly save on CPU cycles for sim in ("sentry.interfaces.Message", u"sentry\uff0einterfaces\uff0eMessage"): if sim in data: # Document field is logentry data["logentry"] = data[sim] del data[sim] break if data.get("level"): level = data["level"] if (level and isinstance(level, str) and hasattr(LogLevels, level.lower())): data["level"] = getattr(LogLevels, level.lower()) elif not level: data["level"] = DEFAULT_LOG_LEVEL else: data["level"] = DEFAULT_LOG_LEVEL if not data.get("logger"): data["logger"] = "<missing>" exceptions = [] if data.get("exception"): for exception_data in data["exception"]["values"]: exception_stacktrace = None if exception_data.get("stacktrace"): if exception_data["stacktrace"]: exception_stacktrace = _process_stacktrace( exception_data["stacktrace"]["frames"]) del exception_data["stacktrace"]["frames"] else: exception_stacktrace.pop("stacktrace") exception = ExceptionModel(**exception_data) if exception_stacktrace: exception.stacktrace.frames = exception_stacktrace exceptions.append(exception) del data["exception"] stacktrace = None if data.get("stacktrace"): if data["stacktrace"]: frames = _process_stacktrace(data["stacktrace"]["frames"]) del data["stacktrace"]["frames"] stacktrace = Stacktrace(**data.pop("stacktrace")) stacktrace.frames = frames else: data.pop("stacktrace") request_data = None if data.get("request"): if data["request"]: request_data = RequestModel(**data["request"]) data.pop("request") template = None if data.get("template"): if data["template"]: template = Template(**data["template"]) data.pop("template") user = None if data.get("user"): if data["user"]: if data["user"].get("id"): data["user"]["user_id"] = data["user"]["id"] del data["user"]["id"] user = UserModel(**data["user"]) data.pop("user") if data.get("query"): if data["query"]: data["sql_query"] = data["query"] data.pop("query") for deprecated in ("time_spent", "site"): if data.get(deprecated): data["tags"][deprecated] = data[deprecated] event = Event(**data) if exceptions: event.exceptions = exceptions if stacktrace: event.stacktrace = stacktrace if request_data: event.request = request_data if template: event.template = template if user: event.user = user group = EventGroup.query.filter_by(message=event.message, project_id=project_id).first() if not group: if event.logentry: event_type = "Log message" elif event.stacktrace: event_type = "Stacktrace" else: event_type = "Exception" group = EventGroup(message=event.message, project_id=project_id, type=event_type) else: group.last_seen = datetime.now().isoformat() db.session.add(group) event.group = group db.session.add(event) db.session.commit() return event.id
# coding=utf8 # # wsgi.py: cupola application API frontend setup for WSGI servers # Copyright (C) 2015-2016 Sam Black <*****@*****.**> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from cupola.api.run import create_api app = create_api()