def test_anonymous(self, safe_urlread, safe_urlopen, mock_get_all_package_versions): mock_get_all_package_versions.return_value = {"foo": "1.0"} safe_urlread.return_value = json.dumps({"notices": [], "version": {"stable": "1.0.0"}}) assert options.set("system.admin-email", "*****@*****.**") assert options.set("beacon.anonymous", True) send_beacon() install_id = options.get("sentry:install-id") assert install_id and len(install_id) == 40 safe_urlopen.assert_called_once_with( BEACON_URL, json={ "install_id": install_id, "version": sentry.get_version(), "docker": sentry.is_docker(), "python_version": platform.python_version(), "data": { "organizations": 1, "users": 0, "projects": 1, "teams": 1, "events.24h": 0, }, "anonymous": True, "packages": mock_get_all_package_versions.return_value, }, timeout=5, ) safe_urlread.assert_called_once_with(safe_urlopen.return_value) assert options.get("sentry:latest_version") == "1.0.0"
def test_simple(self, safe_urlread, safe_urlopen, mock_get_all_package_versions): mock_get_all_package_versions.return_value = {'foo': '1.0'} safe_urlread.return_value = json.dumps({ 'notices': [], 'version': {'stable': '1.0.0'}, }) assert options.set('system.admin-email', '*****@*****.**') send_beacon() install_id = options.get('sentry:install-id') assert install_id and len(install_id) == 40 safe_urlopen.assert_called_once_with(BEACON_URL, json={ 'install_id': install_id, 'version': sentry.get_version(), 'docker': sentry.is_docker(), 'data': { 'organizations': 1, 'users': 0, 'projects': 1, 'teams': 1, 'events.24h': 0, }, 'admin_email': '*****@*****.**', 'packages': mock_get_all_package_versions.return_value, }, timeout=5) safe_urlread.assert_called_once_with(safe_urlopen.return_value) assert options.get('sentry:latest_version') == '1.0.0'
def test_simple(self, safe_urlread, safe_urlopen, mock_get_all_package_versions): mock_get_all_package_versions.return_value = {'foo': '1.0'} safe_urlread.return_value = json.dumps({ 'notices': [], 'version': { 'stable': '1.0.0' }, }) assert options.set('system.admin-email', '*****@*****.**') assert options.set('beacon.anonymous', False) send_beacon() install_id = options.get('sentry:install-id') assert install_id and len(install_id) == 40 safe_urlopen.assert_called_once_with( BEACON_URL, json={ 'install_id': install_id, 'version': sentry.get_version(), 'docker': sentry.is_docker(), 'data': { 'organizations': 1, 'users': 0, 'projects': 1, 'teams': 1, 'events.24h': 0, }, 'anonymous': False, 'admin_email': '*****@*****.**', 'packages': mock_get_all_package_versions.return_value, }, timeout=5 ) safe_urlread.assert_called_once_with(safe_urlopen.return_value) assert options.get('sentry:latest_version') == '1.0.0'
def send_beacon(): """ Send a Beacon to a remote server operated by the Sentry team. See the documentation for more details. """ from sentry import options from sentry.models import Broadcast, Organization, Project, Team, User install_id = options.get("sentry:install-id") if not install_id: install_id = sha1(uuid4().bytes).hexdigest() logger.info("beacon.generated-install-id", extra={"install_id": install_id}) options.set("sentry:install-id", install_id) if not settings.SENTRY_BEACON: logger.info("beacon.skipped", extra={ "install_id": install_id, "reason": "disabled" }) return if settings.DEBUG: logger.info("beacon.skipped", extra={ "install_id": install_id, "reason": "debug" }) return end = timezone.now() events_24h = tsdb.get_sums(model=tsdb.models.internal, keys=["events.total"], start=end - timedelta(hours=24), end=end)["events.total"] # we need this to be explicitly configured and it defaults to None, # which is the same as False anonymous = options.get("beacon.anonymous") is not False payload = { "install_id": install_id, "version": sentry.get_version(), "docker": sentry.is_docker(), "python_version": platform.python_version(), "data": { "users": User.objects.count(), "projects": Project.objects.count(), "teams": Team.objects.count(), "organizations": Organization.objects.count(), "events.24h": events_24h, }, "packages": get_all_package_versions(), "anonymous": anonymous, } if not anonymous: payload["admin_email"] = options.get("system.admin-email") # TODO(dcramer): relay the response 'notices' as admin broadcasts try: request = safe_urlopen(BEACON_URL, json=payload, timeout=5) response = safe_urlread(request) except Exception: logger.warning("beacon.failed", exc_info=True, extra={"install_id": install_id}) return else: logger.info("beacon.sent", extra={"install_id": install_id}) data = json.loads(response) if "version" in data: options.set("sentry:latest_version", data["version"]["stable"]) if "notices" in data: upstream_ids = set() for notice in data["notices"]: upstream_ids.add(notice["id"]) defaults = { "title": notice["title"], "link": notice.get("link"), "message": notice["message"], } # XXX(dcramer): we're missing a unique constraint on upstream_id # so we're using a lock to work around that. In the future we'd like # to have a data migration to clean up the duplicates and add the constraint lock = locks.get("broadcasts:{}".format(notice["id"]), duration=60) with lock.acquire(): affected = Broadcast.objects.filter( upstream_id=notice["id"]).update(**defaults) if not affected: Broadcast.objects.create(upstream_id=notice["id"], **defaults) Broadcast.objects.filter(upstream_id__isnull=False).exclude( upstream_id__in=upstream_ids).update(is_active=False)
def send_beacon(): """ Send a Beacon to a remote server operated by the Sentry team. See the documentation for more details. """ from sentry import options from sentry.models import Broadcast, Organization, Project, Team, User if not settings.SENTRY_BEACON: logger.info('Not sending beacon (disabled)') return install_id = options.get('sentry:install-id') if not install_id: logger.info('Generated installation ID: %s', install_id) install_id = sha1(uuid4().hex).hexdigest() options.set('sentry:install-id', install_id) end = timezone.now() events_24h = tsdb.get_sums( model=tsdb.models.internal, keys=['events.total'], start=end - timedelta(hours=24), end=end, )['events.total'] payload = { 'install_id': install_id, 'version': sentry.get_version(), 'docker': sentry.is_docker(), 'admin_email': options.get('system.admin-email'), 'data': { # TODO(dcramer): we'd also like to get an idea about the throughput # of the system (i.e. events in 24h) 'users': User.objects.count(), 'projects': Project.objects.count(), 'teams': Team.objects.count(), 'organizations': Organization.objects.count(), 'events.24h': events_24h, }, 'packages': get_all_package_versions(), } # TODO(dcramer): relay the response 'notices' as admin broadcasts try: request = safe_urlopen(BEACON_URL, json=payload, timeout=5) response = safe_urlread(request) except Exception: logger.warning('Failed sending beacon', exc_info=True) return data = json.loads(response) if 'version' in data: options.set('sentry:latest_version', data['version']['stable']) if 'notices' in data: upstream_ids = set() for notice in data['notices']: upstream_ids.add(notice['id']) Broadcast.objects.create_or_update(upstream_id=notice['id'], defaults={ 'title': notice['title'], 'link': notice.get('link'), 'message': notice['message'], }) Broadcast.objects.filter(upstream_id__isnull=False, ).exclude( upstream_id__in=upstream_ids, ).update(is_active=False, )
def send_beacon(): """ Send a Beacon to a remote server operated by the Sentry team. See the documentation for more details. """ from sentry import options from sentry.models import Broadcast, Organization, Project, Team, User install_id = options.get('sentry:install-id') if not install_id: install_id = sha1(uuid4().bytes).hexdigest() logger.info('beacon.generated-install-id', extra={'install_id': install_id}) options.set('sentry:install-id', install_id) if not settings.SENTRY_BEACON: logger.info('beacon.skipped', extra={'install_id': install_id, 'reason': 'disabled'}) return if settings.DEBUG: logger.info('beacon.skipped', extra={'install_id': install_id, 'reason': 'debug'}) return end = timezone.now() events_24h = tsdb.get_sums( model=tsdb.models.internal, keys=['events.total'], start=end - timedelta(hours=24), end=end, )['events.total'] # we need this to be explicitly configured and it defaults to None, # which is the same as False anonymous = options.get('beacon.anonymous') is not False payload = { 'install_id': install_id, 'version': sentry.get_version(), 'docker': sentry.is_docker(), 'data': { # TODO(dcramer): we'd also like to get an idea about the throughput # of the system (i.e. events in 24h) 'users': User.objects.count(), 'projects': Project.objects.count(), 'teams': Team.objects.count(), 'organizations': Organization.objects.count(), 'events.24h': events_24h, }, 'packages': get_all_package_versions(), 'anonymous': anonymous, } if not anonymous: payload['admin_email'] = options.get('system.admin-email') # TODO(dcramer): relay the response 'notices' as admin broadcasts try: request = safe_urlopen(BEACON_URL, json=payload, timeout=5) response = safe_urlread(request) except Exception: logger.warning('beacon.failed', exc_info=True, extra={'install_id': install_id}) return else: logger.info('beacon.sent', extra={'install_id': install_id}) data = json.loads(response) if 'version' in data: options.set('sentry:latest_version', data['version']['stable']) if 'notices' in data: upstream_ids = set() for notice in data['notices']: upstream_ids.add(notice['id']) Broadcast.objects.create_or_update( upstream_id=notice['id'], defaults={ 'title': notice['title'], 'link': notice.get('link'), 'message': notice['message'], } ) Broadcast.objects.filter( upstream_id__isnull=False, ).exclude( upstream_id__in=upstream_ids, ).update( is_active=False, )