Exemplo n.º 1
0
def publish_traces() -> None:
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument("config_file",
                            type=argparse.FileType("r"),
                            help="path to a configuration file")
    arg_parser.add_argument(
        "--queue-name",
        default="main",
        help="name of trace queue / publisher config (default: main)",
    )
    arg_parser.add_argument("--debug",
                            default=False,
                            action="store_true",
                            help="enable debug logging")
    arg_parser.add_argument(
        "--app-name",
        default="main",
        metavar="NAME",
        help="name of app to load from config_file (default: main)",
    )
    args = arg_parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.WARNING
    logging.basicConfig(level=level)

    config_parser = configparser.RawConfigParser()
    config_parser.read_file(args.config_file)

    publisher_raw_cfg = dict(
        config_parser.items("trace-publisher:" + args.queue_name))
    publisher_cfg = config.parse_config(
        publisher_raw_cfg,
        {
            "zipkin_api_url":
            config.DefaultFromEnv(config.Endpoint, "BASEPLATE_ZIPKIN_API_URL"),
            "post_timeout":
            config.Optional(config.Integer, POST_TIMEOUT_DEFAULT),
            "max_batch_size":
            config.Optional(config.Integer, MAX_BATCH_SIZE_DEFAULT),
            "retry_limit":
            config.Optional(config.Integer, RETRY_LIMIT_DEFAULT),
            "max_queue_size":
            config.Optional(config.Integer, MAX_QUEUE_SIZE),
        },
    )

    trace_queue = MessageQueue(
        "/traces-" + args.queue_name,
        max_messages=publisher_cfg.max_queue_size,
        max_message_size=MAX_SPAN_SIZE,
    )

    # pylint: disable=maybe-no-member
    inner_batch = TraceBatch(max_size=publisher_cfg.max_batch_size)
    batcher = TimeLimitedBatch(inner_batch, MAX_BATCH_AGE)
    metrics_client = metrics_client_from_config(publisher_raw_cfg)
    publisher = ZipkinPublisher(
        publisher_cfg.zipkin_api_url.address,
        metrics_client,
        post_timeout=publisher_cfg.post_timeout,
    )

    while True:
        message: Optional[bytes]

        try:
            message = trace_queue.get(timeout=0.2)
        except TimedOutError:
            message = None

        try:
            batcher.add(message)
        except BatchFull:
            serialized = batcher.serialize()
            publisher.publish(serialized)
            batcher.reset()
            batcher.add(message)
Exemplo n.º 2
0
def publish_events() -> None:
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument(
        "config_file", type=argparse.FileType("r"), help="path to a configuration file"
    )
    arg_parser.add_argument(
        "--queue-name",
        default="main",
        help="name of event queue / publisher config (default: main)",
    )
    arg_parser.add_argument(
        "--debug", default=False, action="store_true", help="enable debug logging"
    )
    args = arg_parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.WARNING
    logging.basicConfig(level=level)

    config_parser = configparser.RawConfigParser(interpolation=EnvironmentInterpolation())
    config_parser.read_file(args.config_file)
    raw_config = dict(config_parser.items("event-publisher:" + args.queue_name))
    cfg = config.parse_config(
        raw_config,
        {
            "collector": {
                "hostname": config.String,
                "version": config.Optional(config.String, default="2"),
            },
            "key": {"name": config.String, "secret": config.Base64},
            "max_queue_size": config.Optional(config.Integer, MAX_QUEUE_SIZE),
        },
    )

    metrics_client = metrics_client_from_config(raw_config)

    event_queue = MessageQueue(
        "/events-" + args.queue_name,
        max_messages=cfg.max_queue_size,
        max_message_size=MAX_EVENT_SIZE,
    )

    # pylint: disable=maybe-no-member
    serializer = SERIALIZER_BY_VERSION[cfg.collector.version]()
    batcher = TimeLimitedBatch(serializer, MAX_BATCH_AGE)
    publisher = BatchPublisher(metrics_client, cfg)

    while True:
        message: Optional[bytes]

        try:
            message = event_queue.get(timeout=0.2)
        except TimedOutError:
            message = None

        try:
            batcher.add(message)
        except BatchFull:
            serialized = batcher.serialize()
            publisher.publish(serialized)
            batcher.reset()
            batcher.add(message)
Exemplo n.º 3
0
    def configure_observers(
        self, app_config: Optional[config.RawConfig] = None, module_name: Optional[str] = None
    ) -> None:
        """Configure diagnostics observers based on application configuration.

        This installs all the currently supported observers that have settings
        in the configuration file.

        See :py:mod:`baseplate.observers` for the configuration settings
        available for each observer.

        :param app_config: The application configuration which should have
            settings for the error reporter. If not specified, the config must be passed
            to the Baseplate() constructor.
        :param module_name: Name of the root package of the application. If not specified,
            will be guessed from the package calling this function.

        """
        skipped = []

        if app_config:
            if self._app_config:
                raise Exception("pass app_config to the constructor or this method but not both")

            warn_deprecated(
                "Passing configuration to configure_observers is deprecated in "
                "favor of passing it to the Baseplate constructor"
            )
        else:
            app_config = self._app_config

        self.configure_logging()

        if gevent.monkey.is_module_patched("socket"):
            # pylint: disable=cyclic-import
            from baseplate.observers.timeout import TimeoutBaseplateObserver

            timeout_observer = TimeoutBaseplateObserver.from_config(app_config)
            self.register(timeout_observer)
        else:
            skipped.append("timeout")
        if "metrics.tagging" in app_config:
            if "metrics.namespace" in app_config:
                raise ValueError("metrics.namespace not allowed with metrics.tagging")
            from baseplate.lib.metrics import metrics_client_from_config

            metrics_client = metrics_client_from_config(app_config)
            self.configure_tagged_metrics(metrics_client)
        elif "metrics.namespace" in app_config:
            from baseplate.lib.metrics import metrics_client_from_config

            metrics_client = metrics_client_from_config(app_config)
            self.configure_metrics(metrics_client)
        else:
            skipped.append("metrics")

        if "tracing.service_name" in app_config:
            from baseplate.observers.tracing import tracing_client_from_config

            tracing_client = tracing_client_from_config(app_config)
            self.configure_tracing(tracing_client)
        else:
            skipped.append("tracing")

        if "sentry.dsn" in app_config:
            from baseplate.observers.sentry import error_reporter_from_config

            if module_name is None:
                module_name = get_calling_module_name()

            error_reporter = error_reporter_from_config(app_config, module_name)
            self.configure_error_reporting(error_reporter)
        else:
            skipped.append("error_reporter")

        if skipped:
            logger.debug(
                "The following observers are unconfigured and won't run: %s", ", ".join(skipped)
            )
Exemplo n.º 4
0
    def configure_observers(
        self, app_config: Optional[config.RawConfig] = None, module_name: Optional[str] = None
    ) -> None:
        """Configure diagnostics observers based on application configuration.

        This installs all the currently supported observers that have settings
        in the configuration file.

        See :py:mod:`baseplate.observers` for the configuration settings
        available for each observer.

        :param app_config: The application configuration which should have
            settings for the error reporter. If not specified, the config must be passed
            to the Baseplate() constructor.
        :param module_name: Name of the root package of the application. If not specified,
            will be guessed from the package calling this function.

        """
        skipped = []

        app_config = app_config or self._app_config
        if not app_config:
            raise Exception("configuration must be passed to Baseplate() or here")

        self.configure_logging()

        if gevent.monkey.is_module_patched("socket"):
            # pylint: disable=cyclic-import
            from baseplate.observers.timeout import TimeoutBaseplateObserver

            timeout_observer = TimeoutBaseplateObserver.from_config(app_config)
            self.register(timeout_observer)
        else:
            skipped.append("timeout")

        if "metrics.namespace" in app_config:
            from baseplate.lib.metrics import metrics_client_from_config

            metrics_client = metrics_client_from_config(app_config)
            self.configure_metrics(metrics_client)
        else:
            skipped.append("metrics")

        if "tracing.service_name" in app_config:
            from baseplate.observers.tracing import tracing_client_from_config

            tracing_client = tracing_client_from_config(app_config)
            self.configure_tracing(tracing_client)
        else:
            skipped.append("tracing")

        if "sentry.dsn" in app_config:
            from baseplate.observers.sentry import error_reporter_from_config

            if module_name is None:
                module = inspect.getmodule(inspect.stack()[1].frame)
                if not module:
                    raise Exception("failed to detect module name, pass one explicitly")
                module_name = module.__name__

            error_reporter = error_reporter_from_config(app_config, module_name)
            self.configure_error_reporting(error_reporter)
        else:
            skipped.append("error_reporter")

        if skipped:
            logger.debug(
                "The following observers are unconfigured and won't run: %s", ", ".join(skipped)
            )