Add prometheus load parameters #185
3 changed files with 67 additions and 13 deletions
|
@ -61,7 +61,7 @@ class K6:
|
|||
self._k6_dir: str = k6_dir
|
||||
|
||||
command = (
|
||||
f"{self._k6_dir}/k6 run {self._generate_env_variables()} "
|
||||
f"{self._generate_env_variables()}{self._k6_dir}/k6 run {self._generate_k6_variables()} "
|
||||
f"{self._k6_dir}/scenarios/{self.load_params.scenario.value}.js"
|
||||
)
|
||||
user = STORAGE_USER_NAME if self.load_params.scenario == LoadScenario.LOCAL else None
|
||||
|
@ -75,12 +75,12 @@ class K6:
|
|||
def _get_fill_percents(self):
|
||||
fill_percents = self.shell.exec("df -H --output=source,pcent,target | grep frostfs").stdout.split("\n")
|
||||
return [line.split() for line in fill_percents][:-1]
|
||||
|
||||
|
||||
def check_fill_percent(self):
|
||||
fill_percents = self._get_fill_percents()
|
||||
percent_mean = 0
|
||||
for line in fill_percents:
|
||||
percent_mean += float(line[1].split('%')[0])
|
||||
percent_mean += float(line[1].split("%")[0])
|
||||
percent_mean = percent_mean / len(fill_percents)
|
||||
logger.info(f"{self.loader.ip} mean fill percent is {percent_mean}")
|
||||
return percent_mean >= self.load_params.fill_percent
|
||||
|
@ -125,9 +125,9 @@ class K6:
|
|||
self.preset_output = result.stdout.strip("\n")
|
||||
return self.preset_output
|
||||
|
||||
@reporter.step("Generate K6 command")
|
||||
def _generate_env_variables(self) -> str:
|
||||
env_vars = self.load_params.get_env_vars()
|
||||
@reporter.step("Generate K6 variables")
|
||||
def _generate_k6_variables(self) -> str:
|
||||
env_vars = self.load_params.get_k6_vars()
|
||||
|
||||
env_vars[f"{self.load_params.load_type.value.upper()}_ENDPOINTS"] = ",".join(self.endpoints)
|
||||
env_vars["SUMMARY_JSON"] = self.summary_json
|
||||
|
@ -135,6 +135,14 @@ class K6:
|
|||
reporter.attach("\n".join(f"{param}: {value}" for param, value in env_vars.items()), "K6 ENV variables")
|
||||
return " ".join([f"-e {param}='{value}'" for param, value in env_vars.items() if value is not None])
|
||||
|
||||
@reporter.step("Generate env variables")
|
||||
def _generate_env_variables(self) -> str:
|
||||
env_vars = self.load_params.get_env_vars()
|
||||
if not env_vars:
|
||||
return ""
|
||||
reporter.attach("\n".join(f"{param}: {value}" for param, value in env_vars.items()), "ENV variables")
|
||||
return " ".join([f"{param}='{value}'" for param, value in env_vars.items() if value is not None]) + " "
|
||||
|
||||
def get_start_time(self) -> datetime:
|
||||
return datetime.fromtimestamp(self._k6_process.start_time())
|
||||
|
||||
|
@ -188,23 +196,25 @@ class K6:
|
|||
wait_interval = min_wait_interval
|
||||
if self._k6_process is None:
|
||||
assert "No k6 instances were executed"
|
||||
|
||||
|
||||
while timeout > 0:
|
||||
if not self.load_params.fill_percent is None:
|
||||
with reporter.step(f"Check the percentage of filling of all data disks on the node"):
|
||||
if self.check_fill_percent():
|
||||
logger.info(f"Stopping load on because disks is filled more then {self.load_params.fill_percent}%")
|
||||
logger.info(
|
||||
f"Stopping load on because disks is filled more then {self.load_params.fill_percent}%"
|
||||
)
|
||||
event.set()
|
||||
self.stop()
|
||||
return
|
||||
|
||||
|
||||
if event.is_set():
|
||||
self.stop()
|
||||
return
|
||||
|
||||
|
||||
if not self._k6_process.running():
|
||||
return
|
||||
|
||||
|
||||
remaining_time_hours = f"{timeout//3600}h" if timeout // 3600 != 0 else ""
|
||||
remaining_time_minutes = f"{timeout//60%60}m" if timeout // 60 % 60 != 0 else ""
|
||||
logger.info(
|
||||
|
|
|
@ -94,16 +94,18 @@ def metadata_field(
|
|||
string_repr: Optional[bool] = True,
|
||||
distributed: Optional[bool] = False,
|
||||
formatter: Optional[Callable] = None,
|
||||
env_variable: Optional[str] = None,
|
||||
):
|
||||
return field(
|
||||
default=None,
|
||||
metadata={
|
||||
"applicable_scenarios": applicable_scenarios,
|
||||
"preset_argument": preset_param,
|
||||
"env_variable": scenario_variable,
|
||||
"scenario_variable": scenario_variable,
|
||||
"string_repr": string_repr,
|
||||
"distributed": distributed,
|
||||
"formatter": formatter,
|
||||
"env_variable": env_variable,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -172,6 +174,20 @@ class Preset:
|
|||
local: Optional[bool] = metadata_field(grpc_preset_scenarios, "local", None, False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrometheusParams:
|
||||
# Prometheus server URL
|
||||
server_url: Optional[str] = metadata_field(
|
||||
all_load_scenarios, env_variable="K6_PROMETHEUS_RW_SERVER_URL", string_repr=False
|
||||
)
|
||||
# Prometheus trend stats
|
||||
trend_stats: Optional[str] = metadata_field(
|
||||
all_load_scenarios, env_variable="K6_PROMETHEUS_RW_TREND_STATS", string_repr=False
|
||||
)
|
||||
# Additional tags
|
||||
metrics_tags: Optional[str] = metadata_field(all_load_scenarios, None, "METRIC_TAGS", False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class LoadParams:
|
||||
# ------- CONTROL PARAMS -------
|
||||
|
@ -223,6 +239,10 @@ class LoadParams:
|
|||
fill_percent: Optional[float] = None
|
||||
# if set, the payload is generated on the fly and is not read into memory fully.
|
||||
streaming: Optional[int] = metadata_field(all_load_scenarios, None, "STREAMING", False)
|
||||
# Output format
|
||||
output: Optional[str] = metadata_field(all_load_scenarios, None, "K6_OUT", False)
|
||||
# Prometheus params
|
||||
prometheus: Optional[PrometheusParams] = None
|
||||
|
||||
# ------- COMMON SCENARIO PARAMS -------
|
||||
# Load time is the maximum duration for k6 to give load. Default is the BACKGROUND_LOAD_DEFAULT_TIME value.
|
||||
|
@ -339,6 +359,17 @@ class LoadParams:
|
|||
if self.preset:
|
||||
self.preset.pregen_json = os.path.join(self.working_dir, f"{load_id}_prepare.json")
|
||||
|
||||
def get_k6_vars(self):
|
||||
env_vars = {
|
||||
meta_field.metadata["scenario_variable"]: meta_field.value
|
||||
for meta_field in self._get_meta_fields(self)
|
||||
if self.scenario in meta_field.metadata["applicable_scenarios"]
|
||||
and meta_field.metadata["scenario_variable"]
|
||||
and meta_field.value is not None
|
||||
}
|
||||
|
||||
return env_vars
|
||||
|
||||
def get_env_vars(self):
|
||||
env_vars = {
|
||||
meta_field.metadata["env_variable"]: meta_field.value
|
||||
|
|
|
@ -157,6 +157,7 @@ class TestLoadConfig:
|
|||
"DELETERS": 8,
|
||||
"READ_AGE": 8,
|
||||
"STREAMING": 9,
|
||||
"K6_OUT": "output",
|
||||
"PREGEN_JSON": "pregen_json",
|
||||
"PREPARE_LOCALLY": True,
|
||||
}
|
||||
|
@ -181,6 +182,7 @@ class TestLoadConfig:
|
|||
expected_env_vars = {
|
||||
"DURATION": 9,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"K6_OUT": "output",
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
"K6_SETUP_TIMEOUT": "setup_timeout",
|
||||
|
@ -221,6 +223,7 @@ class TestLoadConfig:
|
|||
"DURATION": 9,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_OUT": "output",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
"K6_SETUP_TIMEOUT": "setup_timeout",
|
||||
"WRITERS": 7,
|
||||
|
@ -254,6 +257,7 @@ class TestLoadConfig:
|
|||
"DURATION": 183900,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_OUT": "output",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
"K6_SETUP_TIMEOUT": "setup_timeout",
|
||||
"NO_VERIFY_SSL": True,
|
||||
|
@ -293,6 +297,7 @@ class TestLoadConfig:
|
|||
"DURATION": 9,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_OUT": "output",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
"K6_SETUP_TIMEOUT": "setup_timeout",
|
||||
"NO_VERIFY_SSL": True,
|
||||
|
@ -332,6 +337,7 @@ class TestLoadConfig:
|
|||
expected_env_vars = {
|
||||
"DURATION": 9,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"K6_OUT": "output",
|
||||
"NO_VERIFY_SSL": True,
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
|
@ -365,6 +371,7 @@ class TestLoadConfig:
|
|||
"CONFIG_FILE": "config_file",
|
||||
"DURATION": 9,
|
||||
"WRITE_OBJ_SIZE": 11,
|
||||
"K6_OUT": "output",
|
||||
"REGISTRY_FILE": "registry_file",
|
||||
"K6_MIN_ITERATION_DURATION": "min_iteration_duration",
|
||||
"K6_SETUP_TIMEOUT": "setup_timeout",
|
||||
|
@ -419,6 +426,7 @@ class TestLoadConfig:
|
|||
"DURATION": 0,
|
||||
"WRITE_OBJ_SIZE": 0,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"WRITERS": 0,
|
||||
|
@ -449,6 +457,7 @@ class TestLoadConfig:
|
|||
"DURATION": 0,
|
||||
"WRITE_OBJ_SIZE": 0,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"MAX_WRITERS": 0,
|
||||
|
@ -486,6 +495,7 @@ class TestLoadConfig:
|
|||
"DURATION": 0,
|
||||
"WRITE_OBJ_SIZE": 0,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"WRITERS": 0,
|
||||
|
@ -516,6 +526,7 @@ class TestLoadConfig:
|
|||
"DURATION": 0,
|
||||
"WRITE_OBJ_SIZE": 0,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"NO_VERIFY_SSL": False,
|
||||
|
@ -554,6 +565,7 @@ class TestLoadConfig:
|
|||
"WRITE_OBJ_SIZE": 0,
|
||||
"NO_VERIFY_SSL": False,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"WRITERS": 0,
|
||||
|
@ -584,6 +596,7 @@ class TestLoadConfig:
|
|||
"DURATION": 0,
|
||||
"WRITE_OBJ_SIZE": 0,
|
||||
"REGISTRY_FILE": "",
|
||||
"K6_OUT": "",
|
||||
"K6_MIN_ITERATION_DURATION": "",
|
||||
"K6_SETUP_TIMEOUT": "",
|
||||
"WRITERS": 0,
|
||||
|
@ -655,7 +668,7 @@ class TestLoadConfig:
|
|||
assert sorted(preset_parameters) == sorted(expected_preset_args)
|
||||
|
||||
def _check_env_vars(self, load_params: LoadParams, expected_env_vars: dict[str, str]):
|
||||
env_vars = load_params.get_env_vars()
|
||||
env_vars = load_params.get_k6_vars()
|
||||
assert env_vars == expected_env_vars
|
||||
|
||||
def _check_all_values_none(self, dataclass, skip_fields=None):
|
||||
|
|
Loading…
Reference in a new issue