예제 #1
0
def main():
    """slo-generator CLI entrypoint."""
    utils.setup_logging()
    args = parse_args(sys.argv[1:])
    export = args.export

    # Load error budget policy
    error_budget_path = utils.normalize(args.error_budget_policy)
    LOGGER.debug(f"Loading Error Budget config from {error_budget_path}")

    error_budget_policy = utils.parse_config(error_budget_path)

    # Parse SLO folder for configs
    slo_config = args.slo_config
    if os.path.isfile(slo_config):
        slo_config_paths = [args.slo_config]
    else:
        slo_config_folder = utils.normalize(slo_config)
        slo_config_paths = glob.glob(f'{slo_config_folder}/slo_*.yaml')

    # Abort if configs are not found
    if not slo_config_paths:
        LOGGER.error(
            f'No SLO configs found in SLO folder {slo_config_folder}.')

    # Load SLO configs and compute SLO reports
    for cfg in slo_config_paths:
        slo_config_path = utils.normalize(cfg)
        LOGGER.debug(f'Loading SLO config from {slo_config_path}')
        slo_config = utils.parse_config(slo_config_path)
        compute(slo_config, error_budget_policy, do_export=export)
 def test_compute_ssm_delete_export(self, *mocks):
     for config in SLO_CONFIGS_SDSM:
         with self.subTest(config=config):
             compute(config,
                     ERROR_BUDGET_POLICY,
                     delete=True,
                     do_export=True)
예제 #3
0
def main(data, context):
    print("Running SLO computations:")
    print("SLO Config: %s" % pprint.pformat(slo_config))
    print("Error Budget Policy: %s" % pprint.pformat(error_budget_policy))
    compute.compute(
        slo_config,
        error_budget_policy,
        timestamp=None,
        client=None,
        do_export=True)
예제 #4
0
def main():
    args = parse_args(sys.argv[1:])
    slo_config_path = utils.normalize(args.slo_config)
    error_budget_path = utils.normalize(args.error_budget_policy)
    export = args.export
    LOGGER.info("Loading SLO config from %s" % slo_config_path)
    LOGGER.info("Loading Error Budget config from %s" % error_budget_path)

    with open(slo_config_path, 'r') as f:
        slo_config = yaml.safe_load(f)

    with open(error_budget_path, 'r') as f:
        error_budget_policy = yaml.safe_load(f)

    compute(slo_config, error_budget_policy, do_export=export)
예제 #5
0
 def test_compute_dummy_obj(self):
     results = compute(slo_config=self.slo_config,
                       error_budget_policy=self.error_budget_policy,
                       backend_obj=DummySLOBackend(),
                       backend_method='dummy_slo_function')
     results = list(results)
     pprint.pprint(results)
예제 #6
0
def cli(args):
    """Main CLI function.

    Args:
        args (Namespace): Argparsed CLI parameters.

    Returns:
        dict: Dict of all reports indexed by config file path.
    """
    utils.setup_logging()
    export = args.export
    delete = args.delete
    timestamp = args.timestamp
    start = time.time()

    # Load error budget policy
    LOGGER.debug(
        f"Loading Error Budget config from {args.error_budget_policy}")
    eb_path = utils.normalize(args.error_budget_policy)
    eb_policy = utils.parse_config(eb_path)

    # Parse SLO folder for configs
    slo_configs = utils.list_slo_configs(args.slo_config)
    if not slo_configs:
        LOGGER.error(f'No SLO configs found in SLO folder {args.slo_config}.')

    # Load SLO configs and compute SLO reports
    all_reports = {}
    for path in slo_configs:
        slo_config_name = path.split("/")[-1]
        LOGGER.debug(f'Loading SLO config "{slo_config_name}"')
        slo_config = utils.parse_config(path)
        reports = compute(slo_config,
                          eb_policy,
                          timestamp=timestamp,
                          do_export=export,
                          delete=delete)
        all_reports[path] = reports
    end = time.time()
    duration = round(end - start, 1)
    LOGGER.info(f'Run summary | SLO Configs: {len(slo_configs)} | '
                f'Error Budget Policy Steps: {len(eb_policy)} | '
                f'Total: {len(slo_configs) * len(eb_policy)} | '
                f'Duration: {duration}s')
    return all_reports
예제 #7
0
def test_slo_config(name):
    slo_config_path = utils.get_slo_config(name)['_path']
    ebp_config_path = os.path.abspath(constants.ERROR_BUDGET_POLICY_PATH)
    try:
        from slo_generator.utils import parse_config
        from slo_generator.compute import compute
        slo_config = parse_config(slo_config_path)
        ebp_config = parse_config(ebp_config_path)
        timestamp = time.time()
        reports = compute(slo_config,
                          ebp_config,
                          timestamp=timestamp,
                          do_export=False)
        return {"success": True, "data": reports}
    except Exception as e:
        app.logger.exception(e)
        return {
            "success": False,
            "errorMessage": f"Test failed: {repr(e)}",
            "traceback": traceback.format_exc()
        }
 def test_compute_elasticsearch(self):
     for config in SLO_CONFIGS_ES:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
 def test_compute_prometheus(self):
     for config in SLO_CONFIGS_PROM:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
 def test_compute_ssm(self, *mocks):
     for config in SLO_CONFIGS_SDSM:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
 def test_compute_stackdriver(self, mock):
     for config in SLO_CONFIGS_SD:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
예제 #12
0
 def test_compute_dynatrace(self, mock):
     for config in SLO_CONFIGS_DT:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
예제 #13
0
 def test_compute_datadog(self):
     for config in SLO_CONFIGS_DD:
         with self.subTest(config=config):
             compute(config, ERROR_BUDGET_POLICY)
예제 #14
0
 def test_compute_dummy_method(self):
     results = compute(slo_config=self.slo_config,
                       error_budget_policy=self.error_budget_policy,
                       backend_method=dummy_slo_function)
     results = list(results)
     pprint.pprint(results)
예제 #15
0
 def test_compute_exponential(self):
     channel = self.make_grpc_stub(nresp=2 * len(self.error_budget_policy))
     patch = mock.patch("google.api_core.grpc_helpers.create_channel")
     with patch as create_channel:
         create_channel.return_value = channel
         compute(self.slo_config_exp, self.error_budget_policy)