Ejemplo n.º 1
0
from flask import Flask
from legal_api.services.bootstrap import AccountService
from legal_api.services.queue import QueueService
from sentry_sdk import capture_message
from sentry_sdk.integrations.logging import LoggingIntegration  # noqa: I001

import config  # pylint: disable=import-error
from utils.logging import setup_logging  # pylint: disable=import-error

# noqa: I003

setup_logging(
    os.path.join(os.path.abspath(os.path.dirname(__file__)), 'logging.conf'))

SENTRY_LOGGING = LoggingIntegration(
    event_level=logging.ERROR  # send errors as events
)
SET_EVENTS_MANUALLY = False


def create_app(run_mode=os.getenv('FLASK_ENV', 'production')):
    """Return a configured Flask App using the Factory method."""
    app = Flask(__name__)
    app.config.from_object(config.CONFIGURATION[run_mode])
    # Configure Sentry
    if app.config.get('SENTRY_DSN', None):
        sentry_sdk.init(dsn=app.config.get('SENTRY_DSN'),
                        integrations=[SENTRY_LOGGING])

    register_shellcontext(app)
Ejemplo n.º 2
0
            "level": "ERROR",
            "handlers": ["console"],
            "propagate": False
        },
        "django.security.DisallowedHost": {
            "level": "ERROR",
            "handlers": ["console"],
            "propagate": False,
        },
    },
}

# Sentry
# ------------------------------------------------------------------------------
SENTRY_DSN = env("SENTRY_DSN")
SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO)

sentry_logging = LoggingIntegration(
    level=SENTRY_LOG_LEVEL,  # Capture info and above as breadcrumbs
    event_level=logging.ERROR,  # Send errors as events
)
sentry_sdk.init(
    dsn=SENTRY_DSN,
    integrations=[sentry_logging,
                  DjangoIntegration(),
                  CeleryIntegration()],
)

# Your stuff...
# ------------------------------------------------------------------------------
Ejemplo n.º 3
0
    import sentry_sdk
    from sentry_sdk.integrations.celery import CeleryIntegration
    from sentry_sdk.integrations.logging import (
        LoggingIntegration, ignore_logger,
    )

    from .sentry import PretixSentryIntegration, setup_custom_filters

    SENTRY_ENABLED = True
    sentry_sdk.init(
        dsn=config.get('sentry', 'dsn'),
        integrations=[
            PretixSentryIntegration(),
            CeleryIntegration(),
            LoggingIntegration(
                level=logging.INFO,
                event_level=logging.CRITICAL
            )
        ],
        environment=SITE_URL,
        release=__version__,
        send_default_pii=False,
    )
    ignore_logger('pretix.base.tasks')
    ignore_logger('django.security.DisallowedHost')
    setup_custom_filters()

CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_DEFAULT_QUEUE = 'default'
CELERY_TASK_QUEUES = (
    Queue('default', routing_key='default.#'),
Ejemplo n.º 4
0
import logging

import discord
import sentry_sdk
from discord.ext.commands import when_mentioned_or
from sentry_sdk.integrations.logging import LoggingIntegration

from bot import constants, patches
from bot.bot import Bot

sentry_logging = LoggingIntegration(level=logging.DEBUG,
                                    event_level=logging.WARNING)

sentry_sdk.init(dsn=constants.Bot.sentry_dsn, integrations=[sentry_logging])

bot = Bot(
    command_prefix=when_mentioned_or(constants.Bot.prefix),
    activity=discord.Game(name="Commands: !help"),
    case_insensitive=True,
    max_messages=10_000,
)

# Internal/debug
bot.load_extension("bot.cogs.error_handler")
bot.load_extension("bot.cogs.filtering")
bot.load_extension("bot.cogs.logging")
bot.load_extension("bot.cogs.security")
bot.load_extension("bot.cogs.config_verifier")

# Commands, etc
bot.load_extension("bot.cogs.antimalware")
Ejemplo n.º 5
0
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), ]
)
Ejemplo n.º 6
0
"""
Initialization of the application with all required configurations.
"""
import logging
import sys

import sentry_sdk
from pythonjsonlogger import jsonlogger
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.logging import ignore_logger, LoggingIntegration

# Sentry init
sentry_sdk.init(
    dsn="https://[email protected]/1367700",
    integrations=[FlaskIntegration(),
                  LoggingIntegration(level='DEBUG')],
)
ignore_logger("werkzeug")


# Logging config
class StackdriverJsonFormatter(jsonlogger.JsonFormatter):
    """
    Formatter for the Stackdriver JSON logs.
    """
    def __init__(self,
                 fmt='%(asctime)s %(levelname)s %(message)s',
                 style='%',
                 *args,
                 **kwargs):
        jsonlogger.JsonFormatter.__init__(self, fmt=fmt, *args, **kwargs)
Ejemplo n.º 7
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

    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

    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()

            # Temporarily also capture counts for one specific transaction to check ingested amount
            if (
                transaction
                and transaction.get("transaction")
                == "/api/0/organizations/{organization_slug}/issues/"
            ):
                metrics.incr("internal.captured.events.envelopes.issues")

            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 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=[
            DjangoIntegration(),
            CeleryIntegration(),
            LoggingIntegration(event_level=None),
            RustInfoIntegration(),
            RedisIntegration(),
        ],
        **sdk_options,
    )
Ejemplo n.º 8
0
from kodiak.queries import Client
from kodiak.queue import RedisWebhookQueue, WebhookEvent

# for info on logging formats see: https://docs.python.org/3/library/logging.html#logrecord-attributes
logging.basicConfig(
    stream=sys.stdout,
    level=conf.LOGGING_LEVEL,
    format="%(levelname)s %(name)s:%(filename)s:%(lineno)d %(message)s",
)

# disable sentry logging middleware as the structlog processor provides more
# info via the extra data field
# TODO(sbdchd): waiting on https://github.com/getsentry/sentry-python/pull/444
# to be merged & released to remove `# type: ignore`
sentry_sdk.init(
    integrations=[LoggingIntegration(level=None, event_level=None)
                  ]  # type: ignore
)

structlog.configure(
    processors=[
        structlog.stdlib.filter_by_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.processors.UnicodeDecoder(),
        SentryProcessor(level=logging.WARNING),
        structlog.processors.KeyValueRenderer(key_order=["event"],
                                              sort_keys=True),
    ],
    context_class=dict,
Ejemplo n.º 9
0
    def __init__(self):

        # We don't want sentry making noise if an error is caught when you don't have internet
        sentry_errors = logging.getLogger('sentry.errors')
        sentry_errors.disabled = True

        sentry_uncaught = logging.getLogger('sentry.errors.uncaught')
        sentry_uncaught.disabled = True

        if SENTRY_SDK_AVAILABLE:
            cacert = None
            if hasattr(sys, "frozen"):
                cacert_resource = get_resource("cacert.pem")
                if cacert_resource is not None and os.path.isfile(
                        cacert_resource):
                    cacert = cacert_resource
                else:
                    log.error(
                        "The SSL certificate bundle file '{}' could not be found"
                        .format(cacert_resource))

            # Don't send log records as events.
            sentry_logging = LoggingIntegration(level=logging.INFO,
                                                event_level=None)

            sentry_sdk.init(dsn=CrashReport.DSN,
                            release=__version__,
                            ca_certs=cacert,
                            default_integrations=False,
                            integrations=[sentry_logging])

            tags = {
                "os:name":
                platform.system(),
                "os:release":
                platform.release(),
                "os:win_32":
                " ".join(platform.win32_ver()),
                "os:mac":
                "{} {}".format(platform.mac_ver()[0],
                               platform.mac_ver()[2]),
                "os:linux":
                " ".join(distro.linux_distribution()),
            }

            with sentry_sdk.configure_scope() as scope:
                for key, value in tags.items():
                    scope.set_tag(key, value)

            extra_context = {
                "python:version":
                "{}.{}.{}".format(sys.version_info[0], sys.version_info[1],
                                  sys.version_info[2]),
                "python:bit":
                struct.calcsize("P") * 8,
                "python:encoding":
                sys.getdefaultencoding(),
                "python:frozen":
                "{}".format(hasattr(sys, "frozen"))
            }

            if sys.platform.startswith("linux") and not hasattr(sys, "frozen"):
                # add locale information
                try:
                    language, encoding = locale.getlocale()
                    extra_context["locale:language"] = language
                    extra_context["locale:encoding"] = encoding
                except ValueError:
                    pass

                # add GNS3 VM version if it exists
                home = os.path.expanduser("~")
                gns3vm_version = os.path.join(home, ".config", "GNS3",
                                              "gns3vm_version")
                if os.path.isfile(gns3vm_version):
                    try:
                        with open(gns3vm_version) as fd:
                            extra_context["gns3vm:version"] = fd.readline(
                            ).strip()
                    except OSError:
                        pass

            with sentry_sdk.configure_scope() as scope:
                for key, value in extra_context.items():
                    scope.set_extra(key, value)
Ejemplo n.º 10
0
import logging

import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration

sentry_logging = LoggingIntegration(
    level=logging.INFO,
    event_level=logging.ERROR,
)

sentry_sdk.init(
    dsn="https://<key>:<secret>@app.getsentry.com/<project>",
    integrations=[sentry_logging],
)

try:
    1 / 0
except Exception as e:
    sentry_sdk.capture_exception(e)
Ejemplo n.º 11
0
from acme_serverless_client.authenticators.http import HTTP01Authenticator
from acme_serverless_client.storage.aws import S3Storage

logger = logging.getLogger("aws-lambda-acme")


if os.environ.get("SENTRY_DSN"):
    import sentry_sdk
    from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
    from sentry_sdk.integrations.logging import LoggingIntegration

    sentry_sdk.init(
        dsn=os.environ["SENTRY_DSN"],
        integrations=[
            AwsLambdaIntegration(),
            LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
        ],
    )


def handler(event: typing.Any, context: typing.Any) -> typing.Mapping[str, typing.Any]:
    client = boto3.client("s3")
    storage = S3Storage(bucket=S3Storage.Bucket(os.environ["BUCKET"], client))
    authenticators = [HTTP01Authenticator(storage=storage)]
    params: typing.Any = {
        "acme_account_email": os.environ["ACME_ACCOUNT_EMAIL"],
        "acme_directory_url": os.environ["ACME_DIRECTORY_URL"],
        "storage": storage,
    }
    if event["action"] == "renew":
        certificates = [
Ejemplo n.º 12
0
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}

# Sentry
if SENTRY_DSN := env('SENTRY_DSN', default=''):
    import sentry_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
    sentry_sdk.init(
        dsn=SENTRY_DSN,
        environment=ENV,
        integrations=[
            DjangoIntegration(),
            CeleryIntegration(),
            RedisIntegration(),
            LoggingIntegration(
                level=logging.INFO,  # Capture info and above as breadcrumbs
                event_level=logging.ERROR,  # Send error events from log messages
            ),
        ],
    )
Ejemplo n.º 13
0
from telegram.ext import Filters
from telegram.ext import CommandHandler
from telegram.ext import CallbackQueryHandler

from eduzen_bot import set_handler
from eduzen_bot.telegram_bot import TelegramBot
from eduzen_bot.callbacks_handler import callback_query

from .plugins.job_queue.alarms.command import set_timer, unset
from .plugins.messages.inline import code_markdown
from .plugins.messages.unknown import unknown
from .plugins.messages.message import parse_msgs

load_dotenv()

sentry_logging = LoggingIntegration(level=logging.DEBUG,
                                    event_level=logging.ERROR)

sentry_sdk.init(
    dsn=os.getenv("SENTRY_DSN", ""),
    integrations=[sentry_logging, TornadoIntegration()],
    release=os.getenv(
        "RELEASE",
        subprocess.check_output(["git", "describe"]).strip().decode("utf8")),
)


def main():
    token = os.getenv("TOKEN")
    eduzen_id = os.getenv("EDUZEN_ID")
    bot = TelegramBot(token, eduzen_id)
Ejemplo n.º 14
0
def config(app):
    """Configure the application"""

    # Sentry (logging)
    if app.config.get('SENTRY_DSN'):

        sentry_logging = LoggingIntegration(
            level=logging.INFO,
            event_level=logging.WARNING
        )

        app.sentry = sentry_sdk.init(
            app.config.get('SENTRY_DSN'),
            integrations=[
                sentry_logging,
                FlaskIntegration(),
                RedisIntegration()
            ]
        )

    # Database (mongo and mongoframes)
    app.mongo = pymongo.MongoClient(app.config['MONGO_URI'])
    app.db = app.mongo.get_default_database()
    mongoframes.Frame._client = app.mongo

    # Database authentication
    if app.config.get('MONGO_PASSWORD'):
        app.db.authenticate(
            app.config.get('MONGO_USERNAME'),
            app.config.get('MONGO_PASSWORD')
            )

    # Database (redis)
    if app.config['REDIS_USE_SENTINEL']:
        sentinel = Sentinel(
            app.config['REDIS_ADDRESS'],
            db=app.config['REDIS_DB'],
            password=app.config['REDIS_PASSWORD'],
            decode_responses=True
        )
        app.redis = sentinel.master_for(app.config['REDIS_SENTINEL_MASTER'])

    else:
        app.redis = StrictRedis(
            host=app.config['REDIS_ADDRESS'][0],
            port=app.config['REDIS_ADDRESS'][1],
            db=app.config['REDIS_DB'],
            password=app.config['REDIS_PASSWORD'],
            decode_responses=True
        )

    # CSRF protection
    forms.CSRF.init_app(app)

    # Manage
    app.manage = manage.Manage(app)

    # Email
    if 'EMAIL_BACKEND' in app.config:
        app.mailer = app.config['EMAIL_BACKEND'].Mailer(
            **app.config.get('EMAIL_BACKEND_SETTINGS')
            )

    # Set the application's default date format for form fields
    forms.fields.DateField.default_format = app.config.get('DATE_FORMAT')

    # Fixes

    # Increase the default cache size for jinja templates
    app.jinja_env.cache = create_cache(1000)

    # REMOTE_ADDR when running behind a proxy server
    app.wsgi_app = ProxyFix(app.wsgi_app)
Ejemplo n.º 15
0
from pycroft.model import session
from pycroft.model.finance import BankAccountActivity
from pycroft.model.session import with_transaction
from pycroft.model.swdd import swdd_vo, swdd_import, swdd_vv
from pycroft.model.task import Task, TaskStatus
from pycroft.model.traffic import TrafficVolume
"""
This module defines celery tasks to run tasks
(as persisted in the database by means of `pycroft.model.task`)
by using implementations as defined in `pycroft.lib.task` (see `TaskImpl`).
"""

if dsn := os.getenv('PYCROFT_SENTRY_DSN'):
    logging_integration = LoggingIntegration(
        level=logging.
        INFO,  # INFO / WARN create breadcrumbs, just as SQL queries
        event_level=logging.ERROR,  # errors and above create breadcrumbs
    )

    sentry_sdk.init(
        dsn=dsn,
        integrations=[CeleryIntegration(), logging_integration],
        traces_sample_rate=1.0,
    )

app = Celery('tasks',
             backend=os.environ['PYCROFT_CELERY_RESULT_BACKEND_URI'],
             broker=os.environ['PYCROFT_CELERY_BROKER_URI'])

logger = get_task_logger(__name__)
Ejemplo n.º 16
0
def main(global_config, **settings):
    dsn = settings.get("sentry.dsn", None)
    if dsn:
        LOGGER.info("Init sentry sdk for {}".format(dsn))
        sentry_sdk.init(
            dsn=dsn,
            integrations=[
                LoggingIntegration(level=None, event_level=None),
                PyramidIntegration()],
            send_default_pii=True,
            request_bodies="always",
            environment=settings.get("sentry.environment", None),
            debug=settings.get("sentry.debug", False),
        )

    config = Configurator(
        autocommit=True,
        settings=settings,
        authentication_policy=AuthenticationPolicy(settings["auth.file"], __name__),
        authorization_policy=AuthorizationPolicy(),
        route_prefix=ROUTE_PREFIX,
    )
    config.include("pyramid_exclog")
    config.include("cornice")
    config.add_forbidden_view(forbidden)
    config.add_view(precondition, context=HTTPPreconditionFailed)
    config.add_request_method(request_params, "params", reify=True)
    config.add_request_method(authenticated_role, reify=True)
    config.add_request_method(check_accreditations)
    config.add_request_method(get_currency_rates, name="currency_rates", reify=True)
    config.add_renderer("json", JSON(serializer=simplejson.dumps))
    config.add_renderer("prettyjson", JSON(indent=4, serializer=simplejson.dumps))
    config.add_renderer("jsonp", JSONP(param_name="opt_jsonp", serializer=simplejson.dumps))
    config.add_renderer("prettyjsonp", JSONP(indent=4, param_name="opt_jsonp", serializer=simplejson.dumps))

    # search for plugins
    plugins = settings.get("plugins") and [plugin.strip() for plugin in settings["plugins"].split(",")]
    for entry_point in iter_entry_points("openprocurement.api.plugins"):
        if not plugins or entry_point.name in plugins:
            plugin = entry_point.load()
            plugin(config)

    # CouchDB connection
    aserver, server, db = set_api_security(settings)
    config.registry.couchdb_server = server
    if aserver:
        config.registry.admin_couchdb_server = aserver
    config.registry.db = db
    # readjust couchdb json decoder
    couchdb_json_decode()

    # Document Service key
    config.registry.docservice_url = settings.get("docservice_url")
    config.registry.docservice_username = settings.get("docservice_username")
    config.registry.docservice_password = settings.get("docservice_password")
    config.registry.docservice_upload_url = settings.get("docservice_upload_url")

    signing_key = settings.get('dockey', '')
    signer = SigningKey(signing_key, encoder=HexEncoder) if signing_key else SigningKey.generate()
    config.registry.docservice_key = signer
    verifier = signer.verify_key

    config.registry.keyring = {
        verifier.encode(encoder=HexEncoder)[:8].decode(): verifier
    }
    dockeys = settings.get('dockeys', '')
    for key in dockeys.split('\0'):
        if key:
            config.registry.keyring[key[:8]] = VerifyKey(key, encoder=HexEncoder)

    # migrate data
    if not os.environ.get("MIGRATION_SKIP"):
        for entry_point in iter_entry_points("openprocurement.api.migrations"):
            plugin = entry_point.load()
            plugin(config.registry)

    config.registry.server_id = settings.get("id", "")

    # search subscribers
    subscribers_keys = [k for k in settings if k.startswith("subscribers.")]
    for k in subscribers_keys:
        subscribers = settings[k].split(",")
        for subscriber in subscribers:
            for entry_point in iter_entry_points("openprocurement.{}".format(k), subscriber):
                if entry_point:
                    plugin = entry_point.load()
                    plugin(config)

    config.registry.health_threshold = float(settings.get("health_threshold", 512))
    config.registry.health_threshold_func = settings.get("health_threshold_func", "all")
    config.registry.update_after = asbool(settings.get("update_after", True))
    return config.make_wsgi_app()
Ejemplo n.º 17
0
        },
        # Errors logged by the SDK itself
        'sentry_sdk': {'level': 'ERROR', 'handlers': ['console'], 'propagate': False},
        'django.security.DisallowedHost': {
            'level': 'ERROR',
            'handlers': ['console'],
            'propagate': False,
        },
    },
}

# Sentry
# ------------------------------------------------------------------------------
SENTRY_DSN = env('SENTRY_DSN')
SENTRY_LOG_LEVEL = env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO)

sentry_logging = LoggingIntegration(
    level=SENTRY_LOG_LEVEL,  # Capture info and above as breadcrumbs
    event_level=None,  # Send no events from log messages
)

{%- if cookiecutter.use_celery == 'y' %}
sentry_sdk.init(  # type: ignore
    dsn=SENTRY_DSN,
    integrations=[sentry_logging, DjangoIntegration(), CeleryIntegration()],
)
{% else %}
sentry_sdk.init(dsn=SENTRY_DSN, integrations=[sentry_logging, DjangoIntegration()])  # type: ignore
{% endif -%}
{% endif %}
Ejemplo n.º 18
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Sentry from a config entry."""

    # Migrate environment from config entry data to config entry options
    if (CONF_ENVIRONMENT not in entry.options
            and CONF_ENVIRONMENT in entry.data
            and entry.data[CONF_ENVIRONMENT]):
        options = {
            **entry.options, CONF_ENVIRONMENT: entry.data[CONF_ENVIRONMENT]
        }
        data = entry.data.copy()
        data.pop(CONF_ENVIRONMENT)
        hass.config_entries.async_update_entry(entry,
                                               data=data,
                                               options=options)

    # https://docs.sentry.io/platforms/python/logging/
    sentry_logging = LoggingIntegration(
        level=entry.options.get(CONF_LOGGING_LEVEL, DEFAULT_LOGGING_LEVEL),
        event_level=entry.options.get(CONF_LOGGING_EVENT_LEVEL,
                                      DEFAULT_LOGGING_EVENT_LEVEL),
    )

    # Additional/extra data collection
    channel = get_channel(current_version)
    huuid = await hass.helpers.instance_id.async_get()
    system_info = await hass.helpers.system_info.async_get_system_info()
    custom_components = await async_get_custom_components(hass)

    tracing = {}
    if entry.options.get(CONF_TRACING):
        tracing = {
            "traces_sample_rate":
            entry.options.get(CONF_TRACING_SAMPLE_RATE,
                              DEFAULT_TRACING_SAMPLE_RATE),
        }

    # pylint: disable-next=abstract-class-instantiated
    sentry_sdk.init(  # type: ignore[abstract]
        dsn=entry.data[CONF_DSN],
        environment=entry.options.get(CONF_ENVIRONMENT),
        integrations=[
            sentry_logging,
            AioHttpIntegration(),
            SqlalchemyIntegration()
        ],
        release=current_version,
        before_send=lambda event, hint: process_before_send(
            hass,
            entry.options,
            channel,
            huuid,
            system_info,
            custom_components,
            event,
            hint,
        ),
        **tracing,
    )

    async def update_system_info(now):
        nonlocal system_info
        system_info = await hass.helpers.system_info.async_get_system_info()

        # Update system info every hour
        async_call_later(hass, 3600, update_system_info)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, update_system_info)

    return True
Ejemplo n.º 19
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)
Ejemplo n.º 20
0
    assert event["_meta"]["request"]["data"]["file"] == {
        "": {
            "len": 0,
            "rem": [["!raw", "x", 0, 0]]
        }
    }
    assert not event["request"]["data"]["file"]


@pytest.mark.parametrize(
    "integrations",
    [
        [flask_sentry.FlaskIntegration()],
        [
            flask_sentry.FlaskIntegration(),
            LoggingIntegration(event_level="ERROR")
        ],
    ],
)
def test_errors_not_reported_twice(sentry_init, integrations, capture_events,
                                   app):
    sentry_init(integrations=integrations)

    @app.route("/")
    def index():
        try:
            1 / 0
        except Exception as e:
            app.logger.exception(e)
            raise e
Ejemplo n.º 21
0
    def __init__(self):
        # We don't want sentry making noise if an error is caught when we don't have internet
        sentry_errors = logging.getLogger('sentry.errors')
        sentry_errors.disabled = True

        sentry_uncaught = logging.getLogger('sentry.errors.uncaught')
        sentry_uncaught.disabled = True
        self._sentry_initialized = False

        if SENTRY_SDK_AVAILABLE:
            cacert = None
            if hasattr(sys, "frozen"):
                cacert_resource = get_resource("cacert.pem")
                if cacert_resource is not None and os.path.isfile(
                        cacert_resource):
                    cacert = cacert_resource
                else:
                    log.error(
                        "The SSL certificate bundle file '{}' could not be found"
                        .format(cacert_resource))

            # Don't send log records as events.
            sentry_logging = LoggingIntegration(level=logging.INFO,
                                                event_level=None)

            sentry_sdk.init(dsn=CrashReport.DSN,
                            release=__version__,
                            ca_certs=cacert,
                            default_integrations=False,
                            integrations=[sentry_logging])

            tags = {
                "os:name":
                platform.system(),
                "os:release":
                platform.release(),
                "os:win_32":
                " ".join(platform.win32_ver()),
                "os:mac":
                "{} {}".format(platform.mac_ver()[0],
                               platform.mac_ver()[2]),
                "os:linux":
                " ".join(distro.linux_distribution()),
            }

            self._add_qt_information(tags)

            with sentry_sdk.configure_scope() as scope:
                for key, value in tags.items():
                    scope.set_tag(key, value)

            extra_context = {
                "python:version":
                "{}.{}.{}".format(sys.version_info[0], sys.version_info[1],
                                  sys.version_info[2]),
                "python:bit":
                struct.calcsize("P") * 8,
                "python:encoding":
                sys.getdefaultencoding(),
                "python:frozen":
                "{}".format(hasattr(sys, "frozen"))
            }

            # extra controller and compute information
            from .controller import Controller
            from .compute_manager import ComputeManager
            extra_context["controller:version"] = Controller.instance(
            ).version()
            extra_context["controller:host"] = Controller.instance().host()
            extra_context["controller:connected"] = Controller.instance(
            ).connected()

            for index, compute in enumerate(
                    ComputeManager.instance().computes()):
                extra_context["compute{}:id".format(index)] = compute.id()
                extra_context["compute{}:name".format(index)] = compute.name(),
                extra_context["compute{}:host".format(index)] = compute.host(),
                extra_context["compute{}:connected".format(
                    index)] = compute.connected()
                extra_context["compute{}:platform".format(
                    index)] = compute.capabilities().get("platform")
                extra_context["compute{}:version".format(
                    index)] = compute.capabilities().get("version")

            with sentry_sdk.configure_scope() as scope:
                for key, value in extra_context.items():
                    scope.set_extra(key, value)
Ejemplo n.º 22
0
import logging.config

import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.integrations.django import DjangoIntegration

from immofake.settings import *


DEBUG = False
SECRET_KEY = os.environ.get(
    "SECRET_KEY", "xrxwegrxgermewnurbctzonyzUZOUNZIUzuzounOZUzouznoUZ"
)

sentry_sdk.init(
    dsn="https://[email protected]/1491457",
    integrations=[DjangoIntegration(), LoggingIntegration()]
)
Ejemplo n.º 23
0
Archivo: app.py Proyecto: urbit/grants
def create_app(config_objects=["grant.settings"]):
    app = Flask(__name__.split(".")[0])
    app.response_class = JSONResponse

    @app.after_request
    def send_emails(response):
        if 'email_sender' in g:
            # starting email sender
            g.email_sender.start()
        return response

    # Return validation errors
    @app.errorhandler(ValidationException)
    def handle_validation_error(err):
        return jsonify({"message": str(err)}), 400

    @app.errorhandler(422)
    @app.errorhandler(400)
    def handle_error(err):
        headers = err.data.get("headers", None)
        messages = err.data.get("messages", "Invalid request.")
        error_message = "Something was wrong with your request"
        if type(messages) == dict:
            if 'json' in messages:
                error_message = messages['json'][0]
            else:
                key = list(messages.keys())[0]
                error_message = "{}: {}".format(camel_to_words(key),
                                                messages[key][0])
        if headers:
            return jsonify({"message": error_message}), err.code, headers
        else:
            return jsonify({"message": error_message}), err.code

    @app.errorhandler(404)
    def handle_notfound_error(err):
        error_message = "Unknown route '{} {}'".format(request.method,
                                                       request.path)
        return jsonify({"message": error_message}), 404

    @app.errorhandler(429)
    def handle_limit_error(err):
        app.logger.warn(
            f'Rate limited request to {request.method} {request.path} from ip {request.remote_addr}'
        )
        return jsonify({
            "message":
            "You’ve done that too many times, please wait and try again later"
        }), 429

    @app.errorhandler(Exception)
    def handle_exception(err):
        sentry_sdk.capture_exception(err)
        app.logger.debug(traceback.format_exc())
        app.logger.debug(
            "Uncaught exception at {} {}, see above for traceback".format(
                request.method, request.path))
        return jsonify({"message": "Something went wrong"}), 500

    for conf in config_objects:
        app.config.from_object(conf)
    app.url_map.strict_slashes = False
    register_extensions(app)
    register_blueprints(app)
    register_shellcontext(app)
    register_commands(app)

    if not (app.config.get("TESTING") or E2E_TESTING):
        sentry_logging = LoggingIntegration(level=logging.INFO,
                                            event_level=logging.ERROR)
        sentry_sdk.init(environment=ENV,
                        release=SENTRY_RELEASE,
                        integrations=[FlaskIntegration(), sentry_logging])

    # handle all AuthExceptions thusly
    # NOTE: testing mode does not honor this handler, and instead returns the generic 500 response
    app.register_error_handler(AuthException, handle_auth_error)

    @app.after_request
    def grantio_authed(response):
        response.headers["X-Grantio-Authed"] = 'yes' if get_authed_user(
        ) else 'no'
        return response

    return app
Ejemplo n.º 24
0
        },
        'newrelic': {
            'handlers': ['console_simple'],
            'level': 'ERROR',
            'propagate': False,
        },
    },
}

EMAIL_BACKEND = 'django_ses.SESBackend'
DEFAULT_FROM_EMAIL = 'NYC Park Alerts <*****@*****.**>'
ADMINS = (('Simon', '*****@*****.**'), )
SERVER_EMAIL = DEFAULT_FROM_EMAIL

sentry_logging = LoggingIntegration(
    level=logging.INFO,
    event_level=logging.WARNING,
)
ignore_logger("newrelic")
sentry_sdk.init(
    dsn=os.environ.get('SENTRY_DSN'),
    integrations=[
        DjangoIntegration(),
        sentry_logging,
    ],
)

django_heroku.settings(locals(), logging=False)

DATABASES['default'][
    'ENGINE'] = 'django_db_geventpool.backends.postgresql_psycopg2'  # noqa: F821
DATABASES['default']['CONN_MAX_AGE'] = 0  # noqa: F821
Ejemplo n.º 25
0
Archivo: worker.py Proyecto: uetchy/moa
from moa.toot import Toot
from moa.toot_poster import TootPoster
from moa.tweet import Tweet
from moa.tweet_poster import TweetPoster

start_time = time.time()

moa_config = os.environ.get('MOA_CONFIG', 'DevelopmentConfig')
c = getattr(importlib.import_module('config'), moa_config)

if c.SENTRY_DSN:
    import sentry_sdk
    from sentry_sdk.integrations.logging import LoggingIntegration

    sentry_logging = LoggingIntegration(
        level=logging.INFO,  # Capture info and above as breadcrumbs
        event_level=logging.FATAL  # Only send fatal errors as events
    )
    sentry_sdk.init(dsn=c.SENTRY_DSN, integrations=[sentry_logging])

parser = argparse.ArgumentParser(description='Moa Worker')
parser.add_argument('--worker',
                    dest='worker',
                    type=int,
                    required=False,
                    default=1)
args = parser.parse_args()

worker_stat = WorkerStat(worker=args.worker)
worker_stat.time = 0

FORMAT = "%(asctime)-15s [%(process)d] [%(filename)s:%(lineno)s : %(funcName)s()] %(message)s"
Ejemplo n.º 26
0
from dotenv import load_dotenv
from sentry_sdk.integrations.logging import LoggingIntegration

load_dotenv()
logging.basicConfig(stream=sys.stdout, level=logging.INFO)

CLOUDFLARE_ZONE_ID = 'a1e41feb30b74a973151948cbe32bdb5'
CLOUDFLARE_DNS_RECORD_ID = 'c69efb02e3b37ba29973edc34e1ed35a'
CLOUDFLARE_reqHeaders = {}
CLOUDFLARE_reqHeaders['Content-type'] = 'application/json'
CLOUDFLARE_reqHeaders['X-Auth-Key'] = os.environ['CLOUDFLARE_API_KEY']
CLOUDFLARE_reqHeaders['X-Auth-Email'] = os.environ['CLOUDFLARE_API_EMAIL']
SENTRY_DSN = os.environ['SENTRY_DSN']

sentry_logging = LoggingIntegration(
    level=logging.INFO,  # Capture info and above as breadcrumbs
    event_level=logging.ERROR  # Send errors as events
)
sentry_sdk.init(dsn=SENTRY_DSN, integrations=[sentry_logging])


def getMyIP():
    yoConn = http.client.HTTPSConnection('api.ipify.org')
    yoConn.request('GET', '/')
    yoResp = yoConn.getresponse()
    data = yoResp.read().decode('utf-8')
    ipaddress.ip_address(data)  # valdiate returned value is a valid IP address
    return data


def getDNSRecord():
    reqUrl = '/client/v4/zones/' + CLOUDFLARE_ZONE_ID + '/dns_records/' + CLOUDFLARE_DNS_RECORD_ID
Ejemplo n.º 27
0
    import win32event
    import servicemanager

import daemonizer

sys.path.append(
    '/laika/dist/rel/prod_tools/Linux_26/STUDIO_TESTING_LATEST/lib/python')
import shotgun_api3 as sg
from shotgun_api3.lib.sgtimezone import SgTimezone

SG_TIMEZONE = SgTimezone()

import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration

sentry_logging = LoggingIntegration(level=logging.WARN,
                                    event_level=logging.ERROR)
sentry = sentry_sdk.init(
    dsn="https://[email protected]/65",
    ca_certs="/etc/ssl/certs/ca-bundle.crt",
    send_default_pii=True,
    integrations=[sentry_logging],
)

CURRENT_PYTHON_VERSION = StrictVersion(sys.version.split()[0])
PYTHON_25 = StrictVersion('2.5')
PYTHON_26 = StrictVersion('2.6')
PYTHON_27 = StrictVersion('2.7')

if CURRENT_PYTHON_VERSION > PYTHON_25:
    EMAIL_FORMAT_STRING = """Time: %(asctime)s
Logger: %(name)s
Ejemplo n.º 28
0
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(message)s")
ch.setFormatter(formatter)
log.addHandler(ch)

sentry_sdk.init(
    Tokens.sentry_link.value,
    traces_sample_rate=1.0,
    integrations=[
        AioHttpIntegration(),
        ThreadingIntegration(),
        LoggingIntegration(),
        ModulesIntegration(),
    ],
)

FATESLIST_BASE_URI = 'https://api.fateslist.xyz/'
DISCORD_SERVERVICES_BASE_URI = 'https://api.discordservices.net/bot/'


async def post_handler(method: Methods,
                       url: str,
                       header: Optional[Dict] = None,
                       headers: Optional[Dict] = None,
                       data: Optional[Dict] = None,
                       json: Optional[Dict] = None,
                       log_data: Optional[bool] = False,
Ejemplo n.º 29
0
@pytest.mark.parametrize("logger", [logger, other_logger])
def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
    sentry_init(integrations=[LoggingIntegration(event_level="ERROR")])
    events = capture_events()

    logger.info("bread")
    logger.critical("LOL")
    event, = events
    assert event["level"] == "fatal"
    assert not event["logentry"]["params"]
    assert event["logentry"]["message"] == "LOL"
    assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])


@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
def test_logging_defaults(integrations, sentry_init, capture_events):
    sentry_init(integrations=integrations)
    events = capture_events()

    logger.info("bread")
    logger.critical("LOL")
    event, = events

    assert event["level"] == "fatal"
    assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])
    assert not any(crumb["message"] == "LOL" for crumb in event["breadcrumbs"])
    assert "threads" not in event


def test_logging_extra_data(sentry_init, capture_events):
Ejemplo n.º 30
0
def setup_bot(backend_name: str, logger, config, restore=None) -> ErrBot:
    # from here the environment is supposed to be set (daemon / non daemon,
    # config.py in the python path )

    bot_config_defaults(config)

    if hasattr(config, 'BOT_LOG_FORMATTER'):
        format_logs(formatter=config.BOT_LOG_FORMATTER)
    else:
        format_logs(theme_color=config.TEXT_COLOR_THEME)

        if config.BOT_LOG_FILE:
            hdlr = logging.FileHandler(config.BOT_LOG_FILE)
            hdlr.setFormatter(
                logging.Formatter(
                    "%(asctime)s %(levelname)-8s %(name)-25s %(message)s"))
            logger.addHandler(hdlr)

    if hasattr(config, 'BOT_LOG_SENTRY') and config.BOT_LOG_SENTRY:
        sentry_integrations = []

        try:
            import sentry_sdk
            from sentry_sdk.integrations.logging import LoggingIntegration

        except ImportError:
            log.exception(
                "You have BOT_LOG_SENTRY enabled, but I couldn't import modules "
                "needed for Sentry integration. Did you install sentry-sdk? "
                "(See https://docs.sentry.io/platforms/python for installation instructions)"
            )
            exit(-1)

        sentry_logging = LoggingIntegration(
            level=config.SENTRY_LOGLEVEL, event_level=config.SENTRY_EVENTLEVEL)

        sentry_integrations.append(sentry_logging)

        if hasattr(config,
                   'BOT_LOG_SENTRY_FLASK') and config.BOT_LOG_SENTRY_FLASK:
            try:
                from sentry_sdk.integrations.flask import FlaskIntegration
            except ImportError:
                log.exception(
                    "You have BOT_LOG_SENTRY enabled, but I couldn't import modules "
                    "needed for Sentry integration. Did you install sentry-sdk[flask]? "
                    "(See https://docs.sentry.io/platforms/python/flask for installation instructions)"
                )
                exit(-1)

            sentry_integrations.append(FlaskIntegration())

        try:
            if hasattr(config, 'SENTRY_TRANSPORT') and isinstance(
                    config.SENTRY_TRANSPORT, tuple):
                mod = importlib.import_module(config.SENTRY_TRANSPORT[1])
                transport = getattr(mod, config.SENTRY_TRANSPORT[0])

                sentry_sdk.init(dsn=config.SENTRY_DSN,
                                integrations=sentry_integrations,
                                transport=transport)
            else:
                sentry_sdk.init(dsn=config.SENTRY_DSN,
                                integrations=sentry_integrations)
        except ImportError:
            log.exception(
                f'Unable to import selected SENTRY_TRANSPORT - {config.SENTRY_TRANSPORT}'
            )
            exit(-1)

    logger.setLevel(config.BOT_LOG_LEVEL)

    storage_plugin = get_storage_plugin(config)

    # init the botplugin manager
    botplugins_dir = path.join(config.BOT_DATA_DIR, PLUGINS_SUBDIR)
    if not path.exists(botplugins_dir):
        makedirs(botplugins_dir, mode=0o755)

    backendpm = BackendPluginManager(config, 'errbot.backends', backend_name,
                                     ErrBot, CORE_BACKENDS)

    log.info('Found Backend plugin: %s' % backendpm.plugin_info.name)

    try:
        bot = backendpm.load_plugin()
        botpm = BotPluginManager(
            storage_plugin,
            config.BOT_EXTRA_PLUGIN_DIR, config.AUTOINSTALL_DEPS,
            getattr(config, 'CORE_PLUGINS',
                    None), lambda name, clazz: clazz(bot, name),
            getattr(config, 'PLUGINS_CALLBACK_ORDER', (None, )))
        bot.attach_storage_plugin(storage_plugin)
        bot.attach_repo_manager(repo_manager)
        bot.attach_plugin_manager(botpm)
        bot.initialize_backend_storage()

        # restore the bot from the restore script
        if restore:
            # Prepare the context for the restore script
            if 'repos' in bot:
                log.fatal('You cannot restore onto a non empty bot.')
                sys.exit(-1)
            log.info(f'**** RESTORING the bot from {restore}')
            restore_bot_from_backup(restore, bot=bot, log=log)
            print('Restore complete. You can restart the bot normally')
            sys.exit(0)

        errors = bot.plugin_manager.update_plugin_places(
            repo_manager.get_all_repos_paths())
        if errors:
            log.error('Some plugins failed to load:\n' +
                      '\n'.join(errors.values()))
            bot._plugin_errors_during_startup = "\n".join(errors.values())
        return bot
    except Exception:
        log.exception("Unable to load or configure the backend.")
        exit(-1)