def initialize_error_reporting() -> None: """Sets up automated error reporting. Exceptions are reported to sentry. We avoid sending any metadata (local variables, paths, ...) to make sure we don't compromise any data. Only the exception and its stacktrace is logged and only if the exception origins from the `rasa` package.""" import sentry_sdk from sentry_sdk import configure_scope from sentry_sdk.integrations.atexit import AtexitIntegration from sentry_sdk.integrations.dedupe import DedupeIntegration from sentry_sdk.integrations.excepthook import ExcepthookIntegration # key for local testing can be found at # https://sentry.io/settings/rasahq/projects/rasa-open-source/install/python/ # for local testing, set the key using `RASA_EXCEPTION_WRITE_KEY=key rasa <command>` key = sentry_write_key() if not key: return telemetry_id = get_telemetry_id() # this is a very defensive configuration, avoiding as many integrations as # possible. it also submits very little data (exception with error message # and line numbers). sentry_sdk.init( f"https://{key}.ingest.sentry.io/2801673", before_send=strip_sensitive_data_from_sentry_event, integrations=[ ExcepthookIntegration(), DedupeIntegration(), AtexitIntegration(lambda _, __: None), ], send_default_pii=False, # activate PII filter server_name=telemetry_id or "UNKNOWN", ignore_errors=[KeyboardInterrupt, RasaException, NotImplementedError], in_app_include=["rasa"], # only submit errors in this package with_locals=False, # don't submit local variables release=f"rasa-{rasa.__version__}", default_integrations=False, environment="development" if in_continuous_integration() else "production", ) if not telemetry_id: return with configure_scope() as scope: # sentry added these more recently, just a protection in a case where a # user has installed an older version of sentry if hasattr(scope, "set_user"): scope.set_user({"id": telemetry_id}) default_context = _default_context_fields() if hasattr(scope, "set_context"): if "os" in default_context: # os is a nested dict, hence we report it separately scope.set_context("Operating System", default_context.pop("os")) scope.set_context("Environment", default_context)
def init( cls, source_tag: str = None, transport: Optional[Union[Type[sentry_sdk.transport.Transport], Callable[[Any], None]]] = None, secret_values: List[str] = [], ): """ Read sentry data source name (DSN) from env variable and initialize sentry cdk. Args: source_tag: str - Source name to be used in "source" tag for events organazing. transport: Transport or Callable - transport object for transfering sentry event to remote server. Usually used for testing, by default HTTP transport used secret_values: List[str] - list of string that have to be filtered out before sending event to sentry server. """ sentry_dsn = os.environ.get(cls.DSN_ENV_NAME) if sentry_dsn: cls.sentry_enabled = True cls.secret_values = secret_values sentry_sdk.init( sentry_dsn, max_breadcrumbs=cls.MAX_BREADCRUMBS, traces_sample_rate=cls.TRACES_SAMPLE_RATE, before_send=AirbyteSentry.filter_event, before_breadcrumb=AirbyteSentry.filter_breadcrumb, transport=transport, # Use only limited list of integration cause sentry may send # transaction events e.g. it could send httplib request with # url and authorization info over StdlibIntegration and it # would bypass before_send hook. integrations=[ ExcepthookIntegration(always_run=True), AtexitIntegration(), LoggingIntegration(), ], # Disable default integrations cause sentry does not allow to # filter transactions event that could transfer sensitive data default_integrations=False, ) if source_tag: sentry_sdk.set_tag("source", source_tag) sentry_sdk.set_tag("run_id", cls.run_id) cls.source_tag = source_tag
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 initialize_error_reporting() -> None: """Sets up automated error reporting. Exceptions are reported to sentry. We avoid sending any metadata (local variables, paths, ...) to make sure we don't compromise any data. Only the exception and its stacktrace is logged and only if the exception origins from the `rasa` package. """ import sentry_sdk from sentry_sdk.integrations.atexit import AtexitIntegration from sentry_sdk.integrations.dedupe import DedupeIntegration from sentry_sdk.integrations.excepthook import ExcepthookIntegration # key for local testing can be found at # https://sentry.io/settings/rasahq/projects/rasa-open-source/install/python/ # for local testing, set the key using `RASA_EXCEPTION_WRITE_KEY=key rasa <command>` key = sentry_write_key() if not key: return # this is a very defensive configuration, avoiding as many integrations as # possible. it also submits very little data (exception with error message # and line numbers). sentry_sdk.init( f"https://{key}.ingest.sentry.io/2801673", before_send=strip_sensitive_data_from_sentry_event, integrations=[ ExcepthookIntegration(), DedupeIntegration(), AtexitIntegration(lambda _, __: None), ], send_default_pii=False, # activate PII filter server_name=get_telemetry_id() or "UNKNOWN", ignore_errors=[KeyboardInterrupt], in_app_include=["rasa"], # only submit errors in this package with_locals=False, # don't submit local variables release=f"rasa-{rasa.__version__}", default_integrations=False, environment="development" if in_continuous_integration() else "production", )
def configure_extensions(): log.debug("Configuring extensions...") if SENTRY_DSN: sentry_sdk.init( dsn=str(SENTRY_DSN), integrations=[ sentry_logging, AioHttpIntegration(), SqlalchemyIntegration(), StdlibIntegration(), ExcepthookIntegration(), DedupeIntegration(), AtexitIntegration(), ModulesIntegration(), ], environment=ENV, ) with sentry_sdk.configure_scope() as scope: log.debug(f"Using the following tags... ENV_TAGS: {ENV_TAGS}") for k, v in ENV_TAGS.items(): scope.set_tag(k, v)
# Authentication check when uploading files. This can be switched off for development testing if required. # Should always be True on production. AUTHENTICATE_UPLOAD = True # This is set on AWX when the fragalysis-stack is rebuilt. SENTRY_DNS = os.environ.get("FRAGALYSIS_BACKEND_SENTRY_DNS") if DEBUG is False and SENTRY_DNS: # By default only call sentry in staging/production sentry_sdk.init( dsn=SENTRY_DNS, integrations=[ DjangoIntegration(), CeleryIntegration(), RedisIntegration(), ExcepthookIntegration(always_run=True) ], # If you wish to associate users to errors (assuming you are using # django.contrib.auth) you may enable sending PII data. send_default_pii=True) # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get(
from sentry_sdk.hub import Hub from sentry_sdk.integrations.excepthook import ExcepthookIntegration from sentry_sdk.integrations.dedupe import DedupeIntegration from sentry_sdk.integrations.stdlib import StdlibIntegration from sentry_sdk.integrations.modules import ModulesIntegration from sentry_sdk.integrations.argv import ArgvIntegration from helpdesk.config import SENTRY_DSN logger = logging.getLogger(__name__) _client = Client( dsn=SENTRY_DSN, default_integrations=False, integrations=[ ExcepthookIntegration(), DedupeIntegration(), StdlibIntegration(), ModulesIntegration(), ArgvIntegration(), ], max_breadcrumbs=5, attach_stacktrace=True, ) _hub = Hub(_client) def report(msg=None, **kw): if not _hub: return try:
SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True X_FRAME_OPTIONS = 'DENY' SECURE_BROWSER_XSS_FILTER = True SECURE_CONTENT_TYPE_NOSNIFF = True CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'",) # Admin RESTRICT_ADMIN = True ALLOWED_ADMIN_IPS = ['127.0.0.1', '::1', ] ALLOWED_ADMIN_IP_RANGES = ['127.0.0.0/24', '192.168.0.0/16', '172.16.0.0/12', '::/1', ] ALLOWED_ADMIN_PROXY_COUNT = 0 RESTRICTED_APP_NAMES = ['admin', ] # Static files (CSS, JavaScript, Images) STATIC_URL = '/static/' STATICFILES_DIRS = (os.path.join(BASE_PATH, 'static/src', ),) STATIC_ROOT = os.path.join(BASE_PATH, 'static/dist') # Sentry SENTRY_IGNORE_ERRORS = (OSError, ) sentry_sdk.init( dsn=Secrets.get(SecretKey.SENTRY_DSN), before_send=before_send, integrations=[DjangoIntegration(), ExcepthookIntegration(always_run=True), LoggingIntegration(logging.INFO, logging.ERROR), ] )
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)