def test_circular_references(sentry_init, request): sentry_init(default_integrations=False, integrations=[ThreadingIntegration()]) gc.collect() gc.disable() request.addfinalizer(gc.enable) class MyThread(Thread): def run(self): pass t = MyThread() t.start() t.join() del t assert not gc.collect()
def setup_diagnostics(coresys: CoreSys) -> None: """Sentry diagnostic backend.""" _LOGGER.info("Initializing Supervisor Sentry") sentry_sdk.init( dsn="https://[email protected]/5370612", before_send=lambda event, hint: filter_data(coresys, event, hint), auto_enabling_integrations=False, default_integrations=False, integrations=[ AioHttpIntegration(), ExcepthookIntegration(), DedupeIntegration(), AtexitIntegration(), ThreadingIntegration(), LoggingIntegration(level=logging.WARNING, event_level=logging.CRITICAL), ], release=SUPERVISOR_VERSION, max_breadcrumbs=30, )
def test_double_patching(sentry_init, capture_events): sentry_init(default_integrations=False, integrations=[ThreadingIntegration()]) events = capture_events() class MyThread(Thread): def run(self): 1 / 0 ts = [] for _ in range(10): t = MyThread() t.start() ts.append(t) for t in ts: t.join() assert len(events) == 10 for event in events: exception, = event["exception"]["values"] assert exception["type"] == "ZeroDivisionError"
def init() -> None: sentry_sdk.init( "https://[email protected]/77924", default_integrations=False, integrations=[ThreadingIntegration(propagate_hub=True)], release=get_version())
import gc from threading import Thread import pytest from sentry_sdk import configure_scope from sentry_sdk.integrations.threading import ThreadingIntegration @pytest.mark.parametrize("integrations", [[ThreadingIntegration()], []]) def test_handles_exceptions(sentry_init, capture_events, integrations): sentry_init(default_integrations=False, integrations=integrations) events = capture_events() def crash(): 1 / 0 t = Thread(target=crash) t.start() t.join() if integrations: event, = events exception, = event["exception"]["values"] assert exception["type"] == "ZeroDivisionError" assert exception["mechanism"] == { "type": "threading", "handled": False }
def configure_sdk(): from sentry_sdk.integrations.celery import CeleryIntegration from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.integrations.redis import RedisIntegration from sentry_sdk.integrations.threading import ThreadingIntegration assert sentry_sdk.Hub.main.client is None sdk_options = dict(settings.SENTRY_SDK_CONFIG) relay_dsn = sdk_options.pop("relay_dsn", None) internal_project_key = get_project_key() upstream_dsn = sdk_options.pop("dsn", None) sdk_options["traces_sampler"] = traces_sampler sdk_options["release"] = (f"backend@{sdk_options['release']}" if "release" in sdk_options else None) sdk_options["send_client_reports"] = True if upstream_dsn: transport = make_transport(get_options(dsn=upstream_dsn, **sdk_options)) upstream_transport = patch_transport_for_instrumentation( transport, "upstream") else: upstream_transport = None if relay_dsn: transport = make_transport(get_options(dsn=relay_dsn, **sdk_options)) relay_transport = patch_transport_for_instrumentation( transport, "relay") elif internal_project_key and internal_project_key.dsn_private: transport = make_transport( get_options(dsn=internal_project_key.dsn_private, **sdk_options)) relay_transport = patch_transport_for_instrumentation( transport, "relay") else: relay_transport = None _override_on_full_queue(relay_transport, "internal.uncaptured.events.relay") _override_on_full_queue(upstream_transport, "internal.uncaptured.events.upstream") class MultiplexingTransport(sentry_sdk.transport.Transport): def capture_envelope(self, envelope): # Temporarily capture envelope counts to compare to ingested # transactions. metrics.incr("internal.captured.events.envelopes") transaction = envelope.get_transaction_event() if transaction: metrics.incr("internal.captured.events.transactions") # Assume only transactions get sent via envelopes if options.get( "transaction-events.force-disable-internal-project"): return self._capture_anything("capture_envelope", envelope) def capture_event(self, event): if event.get("type") == "transaction" and options.get( "transaction-events.force-disable-internal-project"): return self._capture_anything("capture_event", event) def _capture_anything(self, method_name, *args, **kwargs): # Upstream should get the event first because it is most isolated from # the this sentry installation. if upstream_transport: metrics.incr("internal.captured.events.upstream") # TODO(mattrobenolt): Bring this back safely. # from sentry import options # install_id = options.get('sentry:install-id') # if install_id: # event.setdefault('tags', {})['install-id'] = install_id getattr(upstream_transport, method_name)(*args, **kwargs) if relay_transport and options.get( "store.use-relay-dsn-sample-rate") == 1: # If this is a envelope ensure envelope and it's items are distinct references if method_name == "capture_envelope": args_list = list(args) envelope = args_list[0] relay_envelope = copy.copy(envelope) relay_envelope.items = envelope.items.copy() args = [relay_envelope, *args_list[1:]] if is_current_event_safe(): metrics.incr("internal.captured.events.relay") getattr(relay_transport, method_name)(*args, **kwargs) else: metrics.incr( "internal.uncaptured.events.relay", skip_internal=False, tags={"reason": "unsafe"}, ) sentry_sdk.init( transport=MultiplexingTransport(), integrations=[ DjangoAtomicIntegration(), DjangoIntegration(), CeleryIntegration(), LoggingIntegration(event_level=None), RustInfoIntegration(), RedisIntegration(), ThreadingIntegration(propagate_hub=True), ], **sdk_options, )
def main(): '''Runs the Wahoo! Results scoreboard''' global FILE_WATCHER # pylint: disable=global-statement global IC # pylint: disable=global-statement # Determine if running as a PyInstaller exe bundle dsn = None execution_environment = "source" if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): execution_environment = "executable" dsn = SENTRY_DSN # only report if in executable mode # pylint: disable=abstract-class-instantiated # https://github.com/getsentry/sentry-python/issues/1081 # Initialize Sentry crash reporting sentry_sdk.init( dsn=dsn, sample_rate=1.0, traces_sample_rate=1.0, environment=execution_environment, release=f"wahoo-results@{WAHOO_RESULTS_VERSION}", with_locals=True, integrations=[ThreadingIntegration(propagate_hub=True)], debug=False, ) uname = platform.uname() sentry_sdk.set_tag("os_system", uname.system) sentry_sdk.set_tag("os_release", uname.release) sentry_sdk.set_tag("os_version", uname.version) sentry_sdk.set_tag("os_machine", uname.machine) config = WahooConfig() sentry_sdk.set_user({ "id": config.get_str("client_id"), "ip_address": "{{auto}}", }) hub = sentry_sdk.Hub.current hub.start_session(session_mode="application") bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__))) root = Tk() screen_size = f"{root.winfo_screenwidth()}x{root.winfo_screenheight()}" sentry_sdk.set_context("display", { "size": screen_size, }) root.title("Wahoo! Results") icon_file = os.path.abspath(os.path.join(bundle_dir, 'wahoo-results.ico')) root.iconbitmap(icon_file) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) FILE_WATCHER = watchdog.observers.Observer() FILE_WATCHER.start() IC = ImageCast(8011) settings_window(root, config) # Intercept the close button so we can save the config before destroying # the main window and exiting the event loop in case we need to display an # error dialog. def close_cb(): try: config.save() except PermissionError as err: messagebox.showerror( title="Error saving configuration", message= f'Unable to write configuration file "{err.filename}". {err.strerror}', detail="Please ensure the working directory is writable.") root.destroy() root.protocol("WM_DELETE_WINDOW", close_cb) root.mainloop() FILE_WATCHER.stop() FILE_WATCHER.join() IC.stop()
for key, value in event.items() } elif isinstance(event, list): return [ strip_bot_token(value, hint) for value in event ] elif isinstance(event, str) and BOT_TOKEN_RE.find(event): return BOT_TOKEN_RE.sub(event, '<BOT_TOKEN>') else: return event sentry_sdk.init( dsn='https://[email protected]/1568089', integrations=[SqlalchemyIntegration(), ThreadingIntegration()], before_send=strip_bot_token, ) class LastUpdate(Base): __tablename__ = 'last_update' id = Column(Integer, primary_key=True) update_id = Column(Integer) class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) chat_id = Column(Integer, unique=True)
# Sentry integration SENTRY_DSN = "https://[email protected]/8" env = get_env() _ERROR_REPORTING = CONFIG.y_bool("error_reporting.enabled", False) if _ERROR_REPORTING: # pylint: disable=abstract-class-instantiated sentry_init( dsn=SENTRY_DSN, integrations=[ DjangoIntegration(transaction_style="function_name"), CeleryIntegration(), RedisIntegration(), Boto3Integration(), ThreadingIntegration(propagate_hub=True), ], before_send=before_send, release=f"authentik@{__version__}", traces_sample_rate=float(CONFIG.y("error_reporting.sample_rate", 0.5)), environment=CONFIG.y("error_reporting.environment", "customer"), send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False), ) set_tag("authentik.build_hash", get_build_hash("tagged")) set_tag("authentik.env", env) set_tag("authentik.component", "backend") set_tag("authentik.uuid", sha512(str(SECRET_KEY).encode("ascii")).hexdigest()[:16]) j_print( "Error reporting is enabled", env=CONFIG.y("error_reporting.environment", "customer"),
# Sends exception tracebacks to Sentry, a cloud service for collecting exceptions sentry_sdk.init( config.config["SENTRY_URL"], traces_sample_rate=0.0, environment=config.config["COOKIE_DOMAIN"], release=config.config["VERSION"], default_integrations=False, integrations=[ # we need to manually list out the integrations, there is no other way of disabling the global excepthook integration # we want to disable that because it seems to be picking up already handled gRPC errors (e.g. grpc.StatusCode.NOT_FOUND) LoggingIntegration(), StdlibIntegration(), DedupeIntegration(), AtexitIntegration(), ModulesIntegration(), ThreadingIntegration(), ], ) # used to export metrics create_prometheus_server(main_process_registry, 8000) def log_unhandled_exception(exc_type, exc_value, exc_traceback): """Make sure that any unhandled exceptions will write to the logs""" if issubclass(exc_type, KeyboardInterrupt): # call the default excepthook saved at __excepthook__ sys.__excepthook__(exc_type, exc_value, exc_traceback) return logger.critical("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback))
def init() -> None: sentry_sdk.init( "https://[email protected]/5861866", default_integrations=False, integrations=[ThreadingIntegration(propagate_hub=True)], release=version)
def init() -> None: sentry_sdk.init( "https://*****:*****@sentry.io/1488600", default_integrations=False, integrations=[ThreadingIntegration(propagate_hub=True)], release=version)
def main(): logging.info('main') app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) appctxt = AppContext(app) sentry_sdk.init( "https://[email protected]/5210435", shutdown_timeout=5, default_integrations=False, # Either pyqt or pyinstaller do weird things with sentry, # need to explicitely specify these else sentry fails integrations=[ LoggingIntegration(), StdlibIntegration(), ExcepthookIntegration(), DedupeIntegration(), AtexitIntegration(), ModulesIntegration(), ArgvIntegration(), ThreadingIntegration(), ]) instance = SingleInstance() print('instance', instance) logger = get_logging(appctxt.build_settings['debug']) build_msg = "Production" if appctxt.is_frozen else "Development" logger.info( f"PWUploader, version: {appctxt.build_settings['version']}, {build_msg} build" ) logging.debug(f'config {CONFIG.as_dict()}') signal.signal(signal.SIGINT, signal.SIG_DFL) logo_path = appctxt.get_resource('logo.png') logging.debug(f'logo_path: {logo_path}') icon = QIcon(logo_path) tray = QSystemTrayIcon() tray.setIcon(icon) logging.debug('tray: %s', tray) tray.show() menu = QMenu() # left-click should just open the menu too def on_systray_activated(reason): if reason == 3: menu.popup(QCursor.pos()) tray.activated.connect(on_systray_activated) action0 = QAction(f"Version: v{appctxt.build_settings['version']}") menu.addAction(action0) action2 = QAction('settings') action2.triggered.connect(on_settings(appctxt)) menu.addAction(action2) action3 = QAction('resync files') def connect_missing_files(): upload_missing_files(appctxt, remote_config) action3.triggered.connect(connect_missing_files) menu.addAction(action3) action4 = QAction('open log dir') action4.triggered.connect(on_open_logdir) menu.addAction(action4) def toggle_always_running(state): if state: CONFIG.set('always_running', True) start_guardian_detached() else: CONFIG.set('always_running', False) kill_guardian() with open(CONFIG_FILE, 'w') as f: f.write(json.dumps(CONFIG.as_dict(), indent=2)) logging.info('config saved') action5 = QAction('always running', checkable=True) if CONFIG.get('always_running'): action5.setChecked(True) action5.triggered.connect(toggle_always_running) menu.addAction(action5) action1 = QAction("quit") action1.triggered.connect(on_quit) menu.addAction(action1) tray.setContextMenu(menu) # FIXME get this after app display if possible for i in range(10): api = PWAPI(appctxt, appctxt.build_settings['api_url'], CONFIG.get('api_token'), CONFIG.get('account_id')) remote_config = api.get_config() if 'detail' in remote_config: logging.error('Invalid remote config %s', remote_config) message = 'Unable to reach Pathology Watch API for authentication, are your API Token & Lab ID correct? Click ok to open settings.' response = QtWidgets.QMessageBox.question( None, 'API Error', message, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel) if response == QtWidgets.QMessageBox.Cancel: sys.exit(0) settings_dialog = SettingsDialog(appctxt, CONFIG, CONFIG_FILE) settings_dialog.ui.setWindowModality(QtCore.Qt.ApplicationModal) settings_dialog.ui.exec_() else: break time.sleep(1) if remote_config is not None: clean_remote_config = { k: v for k, v in remote_config.items() if 'secret' not in k } logging.debug(f'remote_config {clean_remote_config}') # TODO verify remote_config if it's not set, check api token or pw connectivity else: logging.error( 'Uploader settings invalid or server isn\'t configured, contact [email protected]' ) sys.exit(1) # FIXME need to validate remote_config, config logging.info('Starting upload watcher') watcher_thread = WatcherThread(CONFIG.get('watch_dir'), trigger_upload) watcher_thread.finished.connect(app.exit) watcher_thread.start() logging.info('Starting heartbeat thread') heartbeat_thread = HeartbeatThread(appctxt, remote_config, CONFIG, upload_missing_files) heartbeat_thread.finished.connect(app.exit) heartbeat_thread.start() worker_threads = [] for i in range(appctxt.build_settings['n_upload_worker_threads']): logging.info(f'Starting worker {i}') worker_thread = WorkerThread(appctxt, remote_config, CONFIG, UPLOAD_QUEUE) worker_thread.finished.connect(app.exit) worker_thread.start() worker_threads.append(worker_thread) #def excepthook(exc_type, exc_value, exc_tb): # import traceback # tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb)) # logging.error("error caught: %s", str(tb)) # capture_exception(exc_type) #sys.excepthook = excepthook exit_code = -1 delay = 2 for i in range(5): logging.info('Starting') exit_code = app.exec_() if exit_code == 0: break logging.info(f'Exit loop {exit_code}, sleeping {delay}') time.sleep(delay) delay = delay**2 logging.info(f'Exited: {exit_code}') sys.exit(exit_code)