コード例 #1
0
def test_disabled(config):
    config['SENTRY']['DSN'] = None
    container = Mock(config=config)

    reporter = SentryReporter().bind(container, "sentry")
    reporter.setup()

    # DSN applied correctly
    assert reporter.client.get_public_dsn() is None
    assert not reporter.client.is_enabled()
コード例 #2
0
def test_setup_without_optional_config(config):

    del config['SENTRY']['CLIENT_CONFIG']
    container = Mock(config=config)

    reporter = SentryReporter().bind(container, "sentry")
    reporter.setup()

    # DSN applied correctly
    assert reporter.client.get_public_dsn() == "//user@localhost:9000/1"
    assert reporter.client.is_enabled()

    # transport set correctly
    transport = reporter.client.remote.get_transport()
    assert isinstance(transport, EventletHTTPTransport)
コード例 #3
0
        class Service(object):
            name = "service"

            sentry = SentryReporter()

            @rpc
            def record_with_helper(self, data):
                breadcrumbs.record(
                    category="worker",
                    message='breadcrumb message',
                    level='warning',
                    data=data
                )
                raise CustomException("Error!")

            @rpc
            def record_directly(self, data):
                self.sentry.captureBreadcrumb(
                    category="worker",
                    message='breadcrumb message',
                    level='warning',
                    data=data
                )
                raise CustomException("Error!")

            @rpc
            def activate_deactivate(self, a, b, c):
                breadcrumbs.record(category="worker", message=a)
                self.sentry.context.deactivate()
                breadcrumbs.record(category="worker", message=b)
                self.sentry.context.activate()
                breadcrumbs.record(category="worker", message=c)
                raise CustomException("Error!")
コード例 #4
0
        class Service(object):
            name = "service"

            sentry = SentryReporter()

            @http('GET', '/resource')
            def resource(self, request):
                raise CustomException()
コード例 #5
0
    class Service(object):
        name = "service"

        sentry = SentryReporter()

        @rpc(expected_exceptions=CustomException)
        def broken(self):
            raise exception_cls("Error!")
コード例 #6
0
def test_expected_exception_not_reported(
    exception_cls, expected_count, config, worker_ctx
):

    exc = exception_cls("Error!")
    exc_info = (exception_cls, exc, None)

    config['SENTRY']['REPORT_EXPECTED_EXCEPTIONS'] = False
    container = Mock(config=config)

    reporter = SentryReporter().bind(container, "sentry")
    reporter.setup()

    with patch.object(reporter.client, 'captureException') as capture:
        reporter.worker_result(worker_ctx, None, exc_info)

    assert capture.call_count == expected_count
コード例 #7
0
        class Service(object):
            name = "service"

            sentry = SentryReporter()

            @http('GET', '/resource')
            def resource(self, request):
                breadcrumbs.record(message=request.query_string)
                raise CustomException()
コード例 #8
0
        class Service(object):
            name = "service"

            sentry = SentryReporter()
            unsafe = Unsafe()

            @rpc
            def broken(self):
                log.info("breadcrumb %s", self.unsafe)
                raise CustomException("Error!")
コード例 #9
0
class ErrorTracking:
    """
    Gives your service Sentry.io error tracking.

    Requires the following values in config.yaml
    SENTRY:
         DSN: ${SENTRY_DSN}
    """

    sentry = SentryReporter()
コード例 #10
0
    class Service(object):
        name = "service"

        sentry = SentryReporter()

        @rpc(expected_exceptions=CustomException)
        def broken(self):
            raise CustomException("Error!")

        @rpc
        def fine(self):
            return "OK"
コード例 #11
0
class HeartbeatService:
    name = "heartbeat_service"

    sentry = SentryReporter()
    dispatch = EventDispatcher()

    @timer(5)
    def send_heartbeat(self):
        timestamp = datetime.now()
        print("Dispatching a heartbeat with timestamp {}".format(timestamp),
              flush=True)
        self.dispatch("heartbeat", timestamp)
コード例 #12
0
        class Service(object):
            name = "service"

            sentry = SentryReporter()

            @rpc
            def broken(self, data):
                self.sentry.context.merge({"arbitrary": data})
                raise CustomException("Error!")

            @rpc
            def get_dsn(self):
                return self.sentry.get_public_dsn()
コード例 #13
0
class GreetingService:
    name = "greetings_service"

    sentry = SentryReporter()

    uid = uuid.uuid4()

    @rpc
    @timeout(3)
    def hello(self, name):
        time.sleep(random.randint(0, int(os.getenv("RANDOM_TIMEOUT", "0"))))
        return "Hello {}, {} is calling!".format(name, GreetingService.uid)

    @event_handler("heartbeat_service", "heartbeat", handler_type=BROADCAST, reliable_delivery=False)
    def on_heartbeat(self, ts):
        print("Received Heartbeat with timestamp {}".format(ts), flush=True)
コード例 #14
0
class SampleService:
    name = "{{ cookiecutter.project_slug }}_service"

    dispatch = EventDispatcher()
    sentry = SentryReporter()
    models = DjangoModels()
    sampleservice = RpcProxy("{{ cookiecutter.project_slug }}_services")

    @event_handler(
        "{{ cookiecutter.project_slug }}", "sync.{{ cookiecutter.project_slug }}.v1", handler_type=SINGLETON,
    )
    def {{ cookiecutter.project_slug }}_sync_handler(self, payload):
        """
        Simple {{ cookiecutter.project_slug }} sample handler
        """
        logging.info("Received event handler %s", {len(payload or [])})
コード例 #15
0
class HttpDemoService:
    name = "http_demo_service"
    sentry = SentryReporter()

    @http("GET", "/broken")
    def broken(self, request):
        raise ConnectionRefusedError()

    @http('GET', '/books/<string:uuid>')
    def demo_get(self, request, uuid):
        data = {'id': uuid, 'title': 'The unbearable lightness of being',
                'author': 'Milan Kundera'}
        return Response(json.dumps({'book': data}),
                        mimetype='application/json')

    @http('POST', '/books')
    def demo_post(self, request):
        return Response(json.dumps({'book': request.data.decode()}),
                        mimetype='application/json')
コード例 #16
0
class LoginService:
    name = "auth_service"
    secret = settings["JWT_SECRET"]

    db = Database(Base)
    sentry = SentryReporter()

    @staticmethod
    def create_token():
        arr = bytearray(32)
        for i in range(0, 32):
            arr[i] = random.randint(0, 255)
        return base64.encodebytes(arr).decode().rstrip()

    @rpc(expected_exceptions=InvalidCredentials)
    @timeout(3)
    def login(self, username, password):
        try:
            rec = self.db.get_session().query(User).filter(
                User.username == username).one()
            if password == rec.password:
                payload = {"userId": rec.userid, "token": self.create_token()}
                return {
                    "access_token":
                    jwt.encode(payload, self.secret,
                               algorithm="HS256").decode().rstrip()
                }
            else:
                raise InvalidCredentials("Wrong password")
        except NoResultFound:
            raise InvalidCredentials("User not found")

    @event_handler("heartbeat_service",
                   "heartbeat",
                   handler_type=BROADCAST,
                   reliable_delivery=False)
    def on_heartbeat(self, ts):
        print("Received Heartbeat with timestamp {}".format(ts), flush=True)
コード例 #17
0
ファイル: service.py プロジェクト: Emplocity/nameko-chassis
class Service:
    """
    Base class for nameko services.
    """

    name = "no name"

    SentryLoggerConfig()
    sentry = SentryReporter()
    config = Config()
    container = ContainerProvider()
    metrics = PrometheusMetrics()

    @rpc
    def say_hello(self) -> str:
        """
        RPC method to ping the service to check if it can be reached.
        """
        return f"Hello from {self.name}!"

    @rpc
    def query_state(self) -> Dict[str, Any]:
        """
        Returns a detailed state of running service.
        """
        return asdict(ServiceState.from_container(self.container))

    @http("GET", "/metrics")
    def serve_metrics(self, request: Request) -> Response:
        """
        Exposes Prometheus metrics over HTTP.
        """
        return self.metrics.expose_metrics(request)

    @rpc
    def set_log_level(self, logger_name: str, level: int) -> str:
        """
        Temporarily override log level in a running service.

        Useful for example for debugging a live service instance, where your
        default log level is INFO or higher to avoid clutter in logs. This
        RPC allows you to change log level while the application is running.

        For example::

            >>> n.rpc.my_service.set_log_level("some.module", logging.DEBUG)

        Now your logs will include debug messages from ``some.module`` even if
        your static log configuration (dictConfig etc.) silenced them.

        Caveat #1: Updating log level in this manner will only affect loggers
        acquired *after* this RPC call. So your code must call
        ``logging.get_logger()`` as late as possible. This unfortunately means
        that library code may or may not be affected - depends on how the
        library acquires its loggers.

        Caveat #2: If your service runs in multiple replicas behind a load
        balancer, you must call this RPC method at least as many times as
        there are replicas to ensure that each replica will have its log level
        changed.
        """
        logger = logging.getLogger(__name__)
        logger_to_change = logging.getLogger(logger_name)
        logger.info(
            f"Updating level for {logger_name} from {logger_to_change.level} to {level}"
        )
        message = f"""
        Log level changed on host {socket.gethostname()}. Revert with:

            n.rpc.{self.name}.set_log_level({logger_name!r}, {logger_to_change.level!r})
        """
        logger_to_change.setLevel(level)
        return message