Esempio n. 1
0
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()
Esempio n. 2
0
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,
    )
Esempio n. 3
0
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"
Esempio n. 4
0
def init() -> None:
    sentry_sdk.init(
        "https://[email protected]/77924",
        default_integrations=False,
        integrations=[ThreadingIntegration(propagate_hub=True)],
        release=get_version())
Esempio n. 5
0
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
        }
Esempio n. 6
0
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,
    )
Esempio n. 7
0
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()
Esempio n. 8
0
            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)
Esempio n. 9
0
# 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"),
Esempio n. 10
0
    # 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))
Esempio n. 11
0
def init() -> None:
    sentry_sdk.init(
        "https://[email protected]/5861866",
        default_integrations=False,
        integrations=[ThreadingIntegration(propagate_hub=True)],
        release=version)
Esempio n. 12
0
def init() -> None:
    sentry_sdk.init(
        "https://*****:*****@sentry.io/1488600",
        default_integrations=False,
        integrations=[ThreadingIntegration(propagate_hub=True)],
        release=version)
Esempio n. 13
0
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)