|
2 | 2 |
|
3 | 3 | import six
|
4 | 4 | import string
|
5 |
| -import pytz |
6 | 5 |
|
7 | 6 | from collections import OrderedDict
|
8 |
| -from dateutil.parser import parse as parse_date |
9 | 7 | from django.db import models
|
10 | 8 | from django.utils import timezone
|
11 | 9 | from django.utils.translation import ugettext_lazy as _
|
@@ -54,10 +52,6 @@ def __init__(self, data, skip_renormalization=False, **kwargs):
|
54 | 52 |
|
55 | 53 |
|
56 | 54 | class EventCommon(object):
|
57 |
| - """ |
58 |
| - Methods and properties common to both Event and SnubaEvent. |
59 |
| - """ |
60 |
| - |
61 | 55 | @classmethod
|
62 | 56 | def generate_node_id(cls, project_id, event_id):
|
63 | 57 | """
|
@@ -365,174 +359,6 @@ def bind_node_data(self):
|
365 | 359 | self.data.bind_data(node_data, ref=ref)
|
366 | 360 |
|
367 | 361 |
|
368 |
| -class SnubaEvent(EventCommon): |
369 |
| - """ |
370 |
| - An event backed by data stored in snuba. |
371 |
| -
|
372 |
| - This is a readonly event and does not support event creation or save. |
373 |
| - The basic event data is fetched from snuba, and the event body is |
374 |
| - fetched from nodestore and bound to the data property in the same way |
375 |
| - as a regular Event. |
376 |
| - """ |
377 |
| - |
378 |
| - # The minimal list of columns we need to get from snuba to bootstrap an |
379 |
| - # event. If the client is planning on loading the entire event body from |
380 |
| - # nodestore anyway, we may as well only fetch the minimum from snuba to |
381 |
| - # avoid duplicated work. |
382 |
| - minimal_columns = ["event_id", "group_id", "project_id", "timestamp"] |
383 |
| - |
384 |
| - __repr__ = sane_repr("project_id", "group_id") |
385 |
| - |
386 |
| - def __init__(self, snuba_values): |
387 |
| - """ |
388 |
| - When initializing a SnubaEvent, think about the attributes you |
389 |
| - might need to access on it. If you only need a few properties, and |
390 |
| - they are all available in snuba, then you should use |
391 |
| - `SnubaEvent.selected_colums` (or a subset depending on your needs) |
392 |
| - But if you know you are going to need the entire event body anyway |
393 |
| - (which requires a nodestore lookup) you may as well just initialize |
394 |
| - the event with `SnubaEvent.minimal_colums` and let the rest of of |
395 |
| - the attributes come from nodestore. |
396 |
| - """ |
397 |
| - assert all(k in snuba_values for k in SnubaEvent.minimal_columns) |
398 |
| - |
399 |
| - # self.snuba_data is a dict of all the stuff we got from snuba |
400 |
| - self.snuba_data = snuba_values |
401 |
| - |
402 |
| - # self.data is a (lazy) dict of everything we got from nodestore |
403 |
| - node_id = SnubaEvent.generate_node_id( |
404 |
| - self.snuba_data["project_id"], self.snuba_data["event_id"] |
405 |
| - ) |
406 |
| - self.data = NodeData(node_id, data=None, wrapper=EventDict) |
407 |
| - |
408 |
| - # ============================================ |
409 |
| - # Snuba-only implementations of properties that |
410 |
| - # would otherwise require nodestore data. |
411 |
| - # ============================================ |
412 |
| - @property |
413 |
| - def tags(self): |
414 |
| - """ |
415 |
| - Override of tags property that uses tags from snuba rather than |
416 |
| - the nodestore event body. This might be useful for implementing |
417 |
| - tag deletions without having to rewrite nodestore blobs. |
418 |
| - """ |
419 |
| - if "tags.key" in self.snuba_data and "tags.value" in self.snuba_data: |
420 |
| - keys = self.snuba_data["tags.key"] |
421 |
| - values = self.snuba_data["tags.value"] |
422 |
| - if keys and values and len(keys) == len(values): |
423 |
| - return sorted(zip(keys, values)) |
424 |
| - else: |
425 |
| - return [] |
426 |
| - else: |
427 |
| - return super(SnubaEvent, self).tags |
428 |
| - |
429 |
| - def get_minimal_user(self): |
430 |
| - from sentry.interfaces.user import User |
431 |
| - |
432 |
| - if all(key in self.snuba_data for key in ["user_id", "email", "username", "ip_address"]): |
433 |
| - user_id = self.snuba_data["user_id"] |
434 |
| - email = self.snuba_data["email"] |
435 |
| - username = self.snuba_data["username"] |
436 |
| - ip_address = self.snuba_data["ip_address"] |
437 |
| - |
438 |
| - return User.to_python( |
439 |
| - {"id": user_id, "email": email, "username": username, "ip_address": ip_address} |
440 |
| - ) |
441 |
| - |
442 |
| - return super(SnubaEvent, self).get_minimal_user() |
443 |
| - |
444 |
| - # If the data for these is available from snuba, we assume |
445 |
| - # it was already normalized on the way in and we can just return |
446 |
| - # it, otherwise we defer to EventCommon implementation. |
447 |
| - def get_event_type(self): |
448 |
| - if "type" in self.snuba_data: |
449 |
| - return self.snuba_data["type"] |
450 |
| - return super(SnubaEvent, self).get_event_type() |
451 |
| - |
452 |
| - @property |
453 |
| - def ip_address(self): |
454 |
| - if "ip_address" in self.snuba_data: |
455 |
| - return self.snuba_data["ip_address"] |
456 |
| - return super(SnubaEvent, self).ip_address |
457 |
| - |
458 |
| - @property |
459 |
| - def title(self): |
460 |
| - if "title" in self.snuba_data: |
461 |
| - return self.snuba_data["title"] |
462 |
| - return super(SnubaEvent, self).title |
463 |
| - |
464 |
| - @property |
465 |
| - def culprit(self): |
466 |
| - if "culprit" in self.snuba_data: |
467 |
| - return self.snuba_data["culprit"] |
468 |
| - return super(SnubaEvent, self).culprit |
469 |
| - |
470 |
| - @property |
471 |
| - def location(self): |
472 |
| - if "location" in self.snuba_data: |
473 |
| - return self.snuba_data["location"] |
474 |
| - return super(SnubaEvent, self).location |
475 |
| - |
476 |
| - # ==================================================== |
477 |
| - # Snuba implementations of the django fields on Event |
478 |
| - # ==================================================== |
479 |
| - @property |
480 |
| - def datetime(self): |
481 |
| - """ |
482 |
| - Reconstruct the datetime of this event from the snuba timestamp |
483 |
| - """ |
484 |
| - # dateutil seems to use tzlocal() instead of UTC even though the string |
485 |
| - # ends with '+00:00', so just replace the TZ with UTC because we know |
486 |
| - # all timestamps from snuba are UTC. |
487 |
| - return parse_date(self.timestamp).replace(tzinfo=pytz.utc) |
488 |
| - |
489 |
| - @property |
490 |
| - def message(self): |
491 |
| - if "message" in self.snuba_data: |
492 |
| - return self.snuba_data["message"] |
493 |
| - return self.data.get("message") |
494 |
| - |
495 |
| - @property |
496 |
| - def platform(self): |
497 |
| - if "platform" in self.snuba_data: |
498 |
| - return self.snuba_data["platform"] |
499 |
| - return self.data.get("platform") |
500 |
| - |
501 |
| - @property |
502 |
| - def id(self): |
503 |
| - # Because a snuba event will never have a django row id, just return |
504 |
| - # the hex event_id here. We should be moving to a world where we never |
505 |
| - # have to reference the row id anyway. |
506 |
| - return self.event_id |
507 |
| - |
508 |
| - @property |
509 |
| - def timestamp(self): |
510 |
| - return self.snuba_data["timestamp"] |
511 |
| - |
512 |
| - @property |
513 |
| - def event_id(self): |
514 |
| - return self.snuba_data["event_id"] |
515 |
| - |
516 |
| - @property |
517 |
| - def project_id(self): |
518 |
| - return self.snuba_data["project_id"] |
519 |
| - |
520 |
| - @project_id.setter |
521 |
| - def project_id(self, value): |
522 |
| - self.snuba_data["project_id"] = value |
523 |
| - |
524 |
| - @property |
525 |
| - def group_id(self): |
526 |
| - return self.snuba_data["group_id"] |
527 |
| - |
528 |
| - @group_id.setter |
529 |
| - def group_id(self, value): |
530 |
| - self.snuba_data["group_id"] = value |
531 |
| - |
532 |
| - def save(self): |
533 |
| - raise NotImplementedError |
534 |
| - |
535 |
| - |
536 | 362 | def ref_func(x):
|
537 | 363 | return x.project_id or x.project.id
|
538 | 364 |
|
|
0 commit comments