def message_top(self): culprit = strip(self.culprit) if culprit: return culprit message = strip(self.message) if not strip(message): return '<unlabeled message>' return truncatechars(message.splitlines()[0], 100)
def serialize(self): if self.stacktrace: stacktrace = self.stacktrace.serialize() else: stacktrace = None return { 'type': strip(self.type) or None, 'value': strip(self.value) or None, 'module': strip(self.module) or None, 'stacktrace': stacktrace, }
def serialize(self): if self.stacktrace: stacktrace = self.stacktrace.serialize() else: stacktrace = None return { "type": strip(self.type) or None, "value": strip(self.value) or None, "module": strip(self.module) or None, "stacktrace": stacktrace, }
def error(self): message = strip(self.get_legacy_message()) if not message: message = '<unlabeled message>' else: message = truncatechars(message.splitlines()[0], 100) return message
def message_short(self): message = strip(self.message) if not message: message = '<unlabeled message>' else: message = truncatechars(message.splitlines()[0], 100) return message
def notify_users(self, group, event, fail_silently=False): repo = self.get_option('repo', group.project) api_endpoint = self.get_option( 'api_endpoint', group.project) or "https://api.github.com/" url = '%srepos/%s/issues' % ( api_endpoint, repo, ) title = event.error() body = '%s\n\n[<a href="%s">View on Sentry</a>]' % (strip( group.culprit), group.get_absolute_url()) labels = self.get_option('label', group.project) data = { "title": title, "body": body, } if labels: data["labels"] = [x.strip() for x in labels.split(",")] req = urllib2.Request(url, json.dumps(data)) req.add_header('User-Agent', 'sentry-notify-github-issues/%s' % self.version) req.add_header( 'Authorization', 'token %s' % self.get_option('access_token', group.project)) req.add_header('Content-Type', 'application/json') resp = urllib2.urlopen(req) data = json.loads(resp.read()) self.create_sentry_issue(group, data["title"], data["html_url"], "GH-%s" % data["number"])
def error(self): message = strip(self.message) if message: message = truncatechars(message, 100) else: message = '<unlabeled message>' return message
def get_metadata(self, data): # Relay normalizes the message for security reports into the log entry # field, so we grab the message from there. # (https://github.com/getsentry/relay/pull/558) message = strip( get_path(data, "logentry", "formatted") or get_path(data, "logentry", "message") ) return {"message": message}
def get_metadata(self): message = strip(self.data.get('message')) if not message: title = '<unlabeled event>' else: title = truncatechars(message.splitlines()[0], 100) return { 'title': title, }
def extract_metadata(self, data): message = strip( get_path(data, "logentry", "formatted") or get_path(data, "logentry", "message")) if message: title = truncatechars(message.splitlines()[0], 100) else: title = "<unlabeled event>" return {"title": title}
def save(self, *args, **kwargs): if not self.last_seen: self.last_seen = timezone.now() if not self.first_seen: self.first_seen = self.last_seen if not self.active_at: self.active_at = self.first_seen # We limit what we store for the message body self.message = strip(self.message) if self.message: self.message = truncatechars(self.message.splitlines()[0], 255) super(Group, self).save(*args, **kwargs)
def get_metadata(self, data): message = strip(get_path(data, 'logentry', 'formatted') or get_path(data, 'logentry', 'message')) if message: title = truncatechars(message.splitlines()[0], 100) else: title = '<unlabeled event>' return { 'title': title, }
def get_metadata(self): message = strip(get_path(self.data, 'logentry', 'formatted') or get_path(self.data, 'logentry', 'message')) if message: title = truncatechars(message.splitlines()[0], 100) else: title = '<unlabeled event>' return { 'title': title, }
def get_metadata(self): # See GH-3248 message_interface = self.data.get('sentry.interfaces.Message', { 'message': self.data.get('message', ''), }) message = strip(message_interface.get('formatted', message_interface['message'])) if not message: title = '<unlabeled event>' else: title = truncatechars(message.splitlines()[0], 100) return { 'title': title, }
def get_context(self, event, is_public=False, **kwargs): last_frame = None interface = event.interfaces.get("sentry.interfaces.Stacktrace") if interface is not None and interface.frames: last_frame = interface.frames[-1] e_module = strip(self.module) e_type = strip(self.type) or "Exception" e_value = strip(self.value) if self.module: fullname = "%s.%s" % (e_module, e_type) else: fullname = e_type return { "is_public": is_public, "event": event, "exception_value": e_value or e_type or "<empty value>", "exception_type": e_type, "exception_module": e_module, "fullname": fullname, "last_frame": last_frame, }
def get_context(self, event, is_public=False, **kwargs): last_frame = None interface = event.interfaces.get('sentry.interfaces.Stacktrace') if interface is not None and interface.frames: last_frame = interface.frames[-1] e_module = strip(self.module) e_type = strip(self.type) or 'Exception' e_value = strip(self.value) if self.module: fullname = '%s.%s' % (e_module, e_type) else: fullname = e_type return { 'is_public': is_public, 'event': event, 'exception_value': e_value or e_type or '<empty value>', 'exception_type': e_type, 'exception_module': e_module, 'fullname': fullname, 'last_frame': last_frame }
def save(self, *args, **kwargs): if not self.last_seen: self.last_seen = timezone.now() if not self.first_seen: self.first_seen = self.last_seen if not self.active_at: self.active_at = self.first_seen # We limit what we store for the message body self.message = strip(self.message) if self.message: self.message = truncatechars(self.message.splitlines()[0], 255) if self.times_seen is None: self.times_seen = 1 self.score = type(self).calculate_score(times_seen=self.times_seen, last_seen=self.last_seen) super().save(*args, **kwargs)
def notify(self, notification): event = notification.event group = event.group project = group.project if not self.is_configured(project): return webhook = self.get_option('webhook', project) username = self.get_option('username', project).strip() icon_url = self.get_option('icon_url', project) title = group.message_short.encode('utf-8') project_name = get_project_full_name(project).encode('utf-8') # event.get description = "[TAG:]\t" + ",".join(["(%s=%s)" % (key, value) for key, value in event.get_tags()]) + \ "\n\n[MESSAGE:]\n" + strip(event.message) payload = { "text": '[%s] %s' % (project_name, title), "attachments": [{ "title": title, "description": description, "url": group.get_absolute_url(), "color": self.color_for_group(group) }], "displayUser": { "name": username.encode('utf-8'), "avatarUrl": "" } } payload['displayUser']['avatarUrl'] = icon_url if icon_url else DEFAULT_IMG values = json.dumps(payload) # Apparently we've stored some bad data from before we used `URLField`. webhook = webhook.strip(' ') return http.safe_urlopen(webhook, method='POST', data=values, headers={"Content-Type":"application/json"})
def get_metadata(self): exception = self.data['sentry.interfaces.Exception']['values'][-1] # Retrieve message message_interface = self.data.get('sentry.interfaces.Message', { 'message': self.data.get('message', ''), }) message = strip(message_interface.get('formatted', message_interface['message'])) # Pick event value if message: value = truncatechars(message.splitlines()[0], 100) else: value = trim(exception.get('value', ''), 1024) # Build metadata return { 'type': trim(exception.get('type', 'Error'), 128), 'value': value, 'message': message, }
def notify_users(self, group, event, fail_silently=False): repo = self.get_option('repo', group.project) api_endpoint = self.get_option('api_endpoint', group.project) or "https://api.github.com/" url = '%srepos/%s/issues' % (api_endpoint, repo,) title = event.error() body = '%s\n\n[<a href="%s">View on Sentry</a>]' % (strip(group.culprit), group.get_absolute_url()) labels = self.get_option('label', group.project) data = { "title": title, "body": body, } if labels: data["labels"] = [x.strip() for x in labels.split(",")] req = urllib2.Request(url, json.dumps(data)) req.add_header('User-Agent', 'sentry-notify-github-issues/%s' % self.version) req.add_header('Authorization', 'token %s' % self.get_option('access_token', group.project)) req.add_header('Content-Type', 'application/json') resp = urllib2.urlopen(req) data = json.loads(resp.read()) self.create_sentry_issue(group, data["title"], data["html_url"], "GH-%s" % data["number"])
def normalize_event_data(self, data): # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip # First we pull out our top-level (non-data attr) kwargs if not data.get("level") or data["level"] not in LOG_LEVELS: data["level"] = logging.ERROR if not data.get("logger"): data["logger"] = DEFAULT_LOGGER_NAME timestamp = data.get("timestamp") if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data["timestamp"] = timestamp if not data.get("event_id"): data["event_id"] = uuid.uuid4().hex data.setdefault("message", None) data.setdefault("culprit", None) data.setdefault("time_spent", None) data.setdefault("server_name", None) data.setdefault("site", None) data.setdefault("checksum", None) data.setdefault("platform", None) data.setdefault("extra", {}) tags = data.get("tags") if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data["tags"] = tags data["message"] = strip(data["message"]) data["culprit"] = strip(data["culprit"]) if not isinstance(data["extra"], dict): # throw it away data["extra"] = {} trim_dict(data["extra"], max_size=MAX_EXTRA_VARIABLE_SIZE) if "sentry.interfaces.Exception" in data: if "values" not in data["sentry.interfaces.Exception"]: data["sentry.interfaces.Exception"] = {"values": [data["sentry.interfaces.Exception"]]} # convert stacktrace + exception into expanded exception if "sentry.interfaces.Stacktrace" in data: data["sentry.interfaces.Exception"]["values"][0]["stacktrace"] = data.pop( "sentry.interfaces.Stacktrace" ) for exc_data in data["sentry.interfaces.Exception"]["values"]: for key in ("type", "module", "value"): value = exc_data.get(key) if value: exc_data[key] = trim(value) if exc_data.get("stacktrace"): for frame in exc_data["stacktrace"]["frames"]: stack_vars = frame.get("vars", {}) trim_dict(stack_vars) if "sentry.interfaces.Stacktrace" in data: for frame in data["sentry.interfaces.Stacktrace"]["frames"]: stack_vars = frame.get("vars", {}) trim_dict(stack_vars) if "sentry.interfaces.Message" in data: msg_data = data["sentry.interfaces.Message"] trim(msg_data["message"], 1024) if msg_data.get("params"): msg_data["params"] = trim(msg_data["params"]) if "sentry.interfaces.Http" in data: http_data = data["sentry.interfaces.Http"] for key in ("cookies", "querystring", "headers", "env", "url"): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get("data") if value: http_data["data"] = trim(value, 2048) # default the culprit to the url if not data["culprit"]: data["culprit"] = trim(strip(http_data.get("url")), MAX_CULPRIT_LENGTH) return data
def title(self): culprit = strip(self.culprit) if culprit: return culprit return self.message
def has_two_part_message(self): message = strip(self.message) return '\n' in message or len(message) > 100
def message_top(self): culprit = strip(self.culprit) if culprit: return culprit return self.error()
def normalize_event_data(self, data): # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip # First we pull out our top-level (non-data attr) kwargs if not data.get('level') or data['level'] not in LOG_LEVELS: data['level'] = logging.ERROR if not data.get('logger'): data['logger'] = DEFAULT_LOGGER_NAME else: data['logger'] = trim(data['logger'], 64) timestamp = data.get('timestamp') if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data['timestamp'] = timestamp if not data.get('event_id'): data['event_id'] = uuid.uuid4().hex data.setdefault('message', None) data.setdefault('culprit', None) data.setdefault('time_spent', None) data.setdefault('server_name', None) data.setdefault('site', None) data.setdefault('checksum', None) data.setdefault('platform', None) data.setdefault('extra', {}) tags = data.get('tags') if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data['tags'] = tags data['message'] = strip(data['message']) data['culprit'] = strip(data['culprit']) if not isinstance(data['extra'], dict): # throw it away data['extra'] = {} trim_dict(data['extra'], max_size=MAX_EXTRA_VARIABLE_SIZE) if 'sentry.interfaces.Exception' in data: if 'values' not in data['sentry.interfaces.Exception']: data['sentry.interfaces.Exception'] = { 'values': [data['sentry.interfaces.Exception']] } # convert stacktrace + exception into expanded exception if 'sentry.interfaces.Stacktrace' in data: data['sentry.interfaces.Exception']['values'][0][ 'stacktrace'] = data.pop('sentry.interfaces.Stacktrace') for exc_data in data['sentry.interfaces.Exception']['values']: for key in ('type', 'module', 'value'): value = exc_data.get(key) if value: exc_data[key] = trim(value) if exc_data.get('stacktrace'): trim_frames(exc_data['stacktrace']) for frame in exc_data['stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) if 'sentry.interfaces.Stacktrace' in data: trim_frames(data['sentry.interfaces.Stacktrace']) for frame in data['sentry.interfaces.Stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) if 'sentry.interfaces.Message' in data: msg_data = data['sentry.interfaces.Message'] trim(msg_data['message'], 1024) if msg_data.get('params'): msg_data['params'] = trim(msg_data['params']) if 'sentry.interfaces.Http' in data: http_data = data['sentry.interfaces.Http'] for key in ('cookies', 'querystring', 'headers', 'env', 'url'): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get('data') if value: http_data['data'] = trim(value, 2048) # default the culprit to the url if not data['culprit']: data['culprit'] = trim(strip(http_data.get('url')), MAX_CULPRIT_LENGTH) return data
def has_two_part_message(self): message = strip(self.get_legacy_message()) return '\n' in message or len(message) > 100
def normalize_event_data(self, data): # First we pull out our top-level (non-data attr) kwargs if not data.get('level') or data['level'] not in LOG_LEVELS: data['level'] = logging.ERROR if not data.get('logger'): data['logger'] = DEFAULT_LOGGER_NAME timestamp = data.get('timestamp') if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data['timestamp'] = timestamp if not data.get('event_id'): data['event_id'] = uuid.uuid4().hex data.setdefault('message', None) data.setdefault('culprit', None) data.setdefault('time_spent', None) data.setdefault('server_name', None) data.setdefault('site', None) data.setdefault('checksum', None) data.setdefault('platform', None) data.setdefault('extra', {}) tags = data.get('tags') if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data['tags'] = tags data['message'] = strip(data['message']) data['culprit'] = strip(data['culprit']) if not isinstance(data['extra'], dict): # throw it away data['extra'] = {} trim_dict(data['extra'], max_size=MAX_EXTRA_VARIABLE_SIZE) # HACK: move this to interfaces code if 'sentry.interfaces.Stacktrace' in data: for frame in data['sentry.interfaces.Stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) if 'sentry.interfaces.Exception' in data: exc_data = data['sentry.interfaces.Exception'] for key in ('type', 'module', 'value'): value = exc_data.get(key) if value: exc_data[key] = trim(value) if 'sentry.interfaces.Message' in data: msg_data = data['sentry.interfaces.Message'] trim(msg_data['message'], 1024) if msg_data.get('params'): msg_data['params'] = trim(msg_data['params']) if 'sentry.interfaces.Http' in data: http_data = data['sentry.interfaces.Http'] for key in ('cookies', 'querystring', 'headers', 'env', 'url'): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get('data') if value: http_data['data'] = trim(value, 2048) # default the culprit to the url if not data['culprit']: data['culprit'] = strip(http_data.get('url')) return data
def normalize_event_data(self, data): # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip # First we pull out our top-level (non-data attr) kwargs if not isinstance(data.get('level'), (basestring, int)): data['level'] = logging.ERROR elif data['level'] not in LOG_LEVELS: data['level'] = logging.ERROR if not data.get('logger'): data['logger'] = DEFAULT_LOGGER_NAME else: data['logger'] = trim(data['logger'], 64) if data.get('platform'): data['platform'] = trim(data['platform'], 64) timestamp = data.get('timestamp') if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data['timestamp'] = timestamp if not data.get('event_id'): data['event_id'] = uuid.uuid4().hex data.setdefault('message', None) data.setdefault('culprit', None) data.setdefault('time_spent', None) data.setdefault('server_name', None) data.setdefault('site', None) data.setdefault('checksum', None) data.setdefault('platform', None) data.setdefault('extra', {}) tags = data.get('tags') if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data['tags'] = tags if not isinstance(data['extra'], dict): # throw it away data['extra'] = {} trim_dict( data['extra'], max_size=settings.SENTRY_MAX_EXTRA_VARIABLE_SIZE) # TODO: each interface should describe its own normalization logic if 'sentry.interfaces.Exception' in data: if 'values' not in data['sentry.interfaces.Exception']: data['sentry.interfaces.Exception'] = { 'values': [data['sentry.interfaces.Exception']] } # convert stacktrace + exception into expanded exception if 'sentry.interfaces.Stacktrace' in data: data['sentry.interfaces.Exception']['values'][0]['stacktrace'] = data.pop('sentry.interfaces.Stacktrace') for exc_data in data['sentry.interfaces.Exception']['values']: for key in ('type', 'module', 'value'): value = exc_data.get(key) if value: exc_data[key] = trim(value) if exc_data.get('stacktrace'): trim_frames(exc_data['stacktrace']) for frame in exc_data['stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) for key, value in frame.iteritems(): if key not in ('vars', 'data'): frame[key] = trim(value) if 'sentry.interfaces.Stacktrace' in data: trim_frames(data['sentry.interfaces.Stacktrace']) for frame in data['sentry.interfaces.Stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) for key, value in frame.iteritems(): if key not in ('vars', 'data'): frame[key] = trim(value) if 'sentry.interfaces.Message' in data: msg_data = data['sentry.interfaces.Message'] trim(msg_data['message'], 1024) if msg_data.get('params'): msg_data['params'] = trim(msg_data['params']) if 'sentry.interfaces.Http' in data: http_data = data['sentry.interfaces.Http'] for key in ('cookies', 'querystring', 'headers', 'env', 'url'): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get('data') if value: http_data['data'] = trim(value, 2048) # default the culprit to the url if not data['culprit']: data['culprit'] = strip(http_data.get('url')) if data['culprit']: data['culprit'] = trim(strip(data['culprit']), MAX_CULPRIT_LENGTH) if data['message']: data['message'] = strip(data['message']) return data