event_context_processors.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. """
  2. Roughly a replacement of sentry/plugins/sentry_useragents but for contexts instead of tags
  3. """
  4. from typing import Optional, Dict
  5. from user_agents import parse
  6. class UserAgentContextProcessor:
  7. """ Abstract class for processing user agent related contexts """
  8. def get_context(self, event) -> Optional[Dict[str, str]]:
  9. headers = event.get("request", {}).get("headers", {})
  10. try:
  11. ua_string = next(x[1] for x in headers if x[0] == "User-Agent")
  12. except StopIteration:
  13. return # Not found
  14. if isinstance(ua_string, list) and len(ua_string) > 0:
  15. ua_string = ua_string[0]
  16. if not ua_string:
  17. return
  18. ua = parse(ua_string)
  19. return self.get_context_from_ua(ua)
  20. @property
  21. def name(self):
  22. raise NotImplementedError()
  23. def get_context_from_ua(self, ua):
  24. raise NotImplementedError()
  25. class BrowserContextProcessor(UserAgentContextProcessor):
  26. """
  27. Browser name (aka family) and version
  28. """
  29. name = "browser"
  30. def get_context_from_ua(self, ua):
  31. context = {"name": ua.browser.family}
  32. if ua.browser.version:
  33. context["version"] = ua.browser.version_string
  34. return context
  35. class OsContextProcessor(UserAgentContextProcessor):
  36. """
  37. Operating System name (aka family) and version
  38. """
  39. name = "os"
  40. def get_context_from_ua(self, ua):
  41. context = {"name": ua.os.family}
  42. if ua.os.version:
  43. context["version"] = ua.os.version_string
  44. return context
  45. class DeviceContextProcessor(UserAgentContextProcessor):
  46. """
  47. Device model, brand, family
  48. This field is fairly unreliable as browsers such as Firefox do not share it
  49. """
  50. name = "device"
  51. def get_context_from_ua(self, ua):
  52. context = {
  53. "family": ua.device.family,
  54. }
  55. if ua.device.model:
  56. context["model"] = ua.device.model
  57. if ua.device.brand:
  58. context["brand"] = ua.device.brand
  59. return context
  60. EVENT_CONTEXT_PROCESSORS = [
  61. BrowserContextProcessor,
  62. OsContextProcessor,
  63. DeviceContextProcessor,
  64. ]