Skip to content

Commit e2a9672

Browse files
committed
Fix db counters (#20386)
1 parent af95436 commit e2a9672

File tree

3 files changed

+115
-14
lines changed

3 files changed

+115
-14
lines changed

ydb/core/base/appdata_fwd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ inline TAppData* AppData(NActors::TActorSystem* actorSystem) {
318318
return x;
319319
}
320320

321+
inline bool HasAppData(NActors::TActorSystem* actorSystem) {
322+
return actorSystem && AppData(actorSystem);
323+
}
324+
321325
inline bool HasAppData() {
322326
return !!NActors::TlsActivationContext
323327
&& NActors::TActivationContext::ActorSystem()

ydb/core/grpc_services/counters/counters.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ NYdbGrpc::ICounterBlockPtr TServiceCounterCB::operator()(const char* serviceName
658658
auto block = MakeIntrusive<TYdbCounterBlock>(Counters, serviceName, requestName, streaming);
659659

660660
NYdbGrpc::ICounterBlockPtr res(block);
661-
if (ActorSystem && HasAppData() && AppData(ActorSystem)->FeatureFlags.GetEnableDbCounters()) {
661+
if (ActorSystem && HasAppData(ActorSystem) && AppData(ActorSystem)->FeatureFlags.GetEnableDbCounters()) {
662662
res = MakeIntrusive<TYdbCounterBlockWrapper>(block, serviceName, requestName, streaming);
663663
}
664664

ydb/tests/functional/tenants/test_db_counters.py

Lines changed: 110 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424

2525
def get_db_counters(mon_port, service):
26-
counters_url = f"http://localhost:{mon_port}/counters/counters%3D{service}/json"
26+
counters_url = f"http://localhost:{mon_port}/counters/counters={service}/json"
2727
reply = requests.get(counters_url)
2828
if reply.status_code == 204:
2929
return None
@@ -144,7 +144,7 @@ def get_default_feature_flag_value(feature_flag_camel_case) -> bool:
144144
ids=["enable_separate_quotas", "disable_separate_quotas"],
145145
)
146146
def ydb_cluster_configuration(request):
147-
extra_feature_flags = []
147+
extra_feature_flags = ['enable_db_counters']
148148
if request.param:
149149
extra_feature_flags.append("enable_separate_disk_space_quotas")
150150
else:
@@ -275,22 +275,37 @@ def wait_for_stats(client, table, retries=10, sleep_duration=5):
275275

276276

277277
# Note: the default total sleep time is 300 seconds, because 200 seconds can sometimes be not enough
278-
def check_counters(mon_port, sensors_to_check, retries=60, sleep_duration=5):
278+
def check_counters(mon_port, sensors_to_check, service="ydb", retries=60, sleep_duration=5):
279+
sensor_count = 0
280+
for _, expected_value in sensors_to_check.items():
281+
if isinstance(expected_value, list):
282+
sensor_count += len(expected_value)
283+
else:
284+
sensor_count += 1
285+
279286
for attempt in range(retries + 1):
280-
counters = get_db_counters(mon_port, "ydb")
287+
counters = get_db_counters(mon_port, service)
281288
correct_sensors = 0
282289
if counters:
283290
for sensor in counters["sensors"]:
291+
labels = sensor["labels"]
284292
for target_name, expected_value in sensors_to_check.items():
285-
if sensor["labels"]["name"] == target_name:
286-
logger.debug(
287-
f"sensor {target_name}: expected {expected_value}, "
288-
f'got {sensor["value"]} in {sleep_duration * attempt} seconds'
289-
)
290-
if sensor["value"] == expected_value:
291-
correct_sensors += 1
292-
if correct_sensors == len(sensors_to_check):
293-
return
293+
if isinstance(expected_value, list):
294+
if labels.get("api_service", "") != target_name:
295+
continue
296+
for x in expected_value:
297+
if len(x) == [labels.get(k, "") == v if k != "value" else sensor[k] == v for k, v in x.items()].count(True):
298+
correct_sensors += 1
299+
else:
300+
if labels["name"] == target_name:
301+
logger.debug(
302+
f"sensor {target_name}: expected {expected_value}, "
303+
f'got {sensor["value"]} in {sleep_duration * attempt} seconds'
304+
)
305+
if sensor["value"] == expected_value:
306+
correct_sensors += 1
307+
if correct_sensors == sensor_count:
308+
return
294309

295310
logger.debug(
296311
f"got {correct_sensors} out of {len(sensors_to_check)} correct sensors "
@@ -403,3 +418,85 @@ def test_storage_counters(self, ydb_cluster_configuration, ydb_cluster, ydb_data
403418
"resources.storage.table.used_bytes.hdd": 0,
404419
},
405420
)
421+
422+
423+
def test_serverless_counters(ydb_cluster, ydb_endpoint, ydb_root, ydb_safe_test_name):
424+
hostel_db = os.path.join(ydb_root, "hostel_db", ydb_safe_test_name)
425+
ydb_cluster.create_hostel_database(
426+
hostel_db,
427+
storage_pool_units_count={
428+
'hdd': 1,
429+
},
430+
)
431+
432+
ydb_cluster.register_and_start_slots(hostel_db, count=1)
433+
ydb_cluster.wait_tenant_up(hostel_db)
434+
435+
serverless_db = os.path.join(ydb_root, "serverless", ydb_safe_test_name)
436+
ydb_cluster.create_serverless_database(
437+
serverless_db,
438+
hostel_db=hostel_db,
439+
attributes={
440+
"cloud_id": "CLOUD_ID_VAL",
441+
"folder_id": "FOLDER_ID_VAL",
442+
"database_id": "DATABASE_ID_VAL",
443+
},
444+
)
445+
446+
driver_config = ydb.DriverConfig(ydb_endpoint, serverless_db, auth_token='root@builtin')
447+
driver = ydb.Driver(driver_config)
448+
driver.wait(120)
449+
450+
session = driver.table_client.session().create()
451+
452+
session.create_table(
453+
os.path.join(serverless_db, "table") ,
454+
ydb.TableDescription()
455+
.with_column(ydb.Column("id", ydb.OptionalType(ydb.DataType.Uint64)))
456+
.with_primary_key("id")
457+
)
458+
459+
try:
460+
session.create_table(
461+
os.path.join(serverless_db, "invalid_table") ,
462+
ydb.TableDescription()
463+
.with_column(ydb.Column("id", ydb.OptionalType(ydb.DataType.Float)))
464+
.with_primary_key("id")
465+
)
466+
except ydb.issues.SchemeError:
467+
pass
468+
469+
slot_mon_port = ydb_cluster.slots[1].mon_port
470+
expected_counters = {
471+
"table": [
472+
{
473+
"method": "CreateSession",
474+
"name": "api.grpc.request.count",
475+
"value": 1,
476+
},
477+
{
478+
"method": "CreateSession",
479+
"name": "api.grpc.response.count",
480+
"status": "SUCCESS",
481+
"value": 1,
482+
},
483+
{
484+
"method": "CreateTable",
485+
"name": "api.grpc.request.count",
486+
"value": 2,
487+
},
488+
{
489+
"method": "CreateTable",
490+
"name": "api.grpc.response.count",
491+
"status": "SUCCESS",
492+
"value": 1,
493+
},
494+
{
495+
"method": "CreateTable",
496+
"name": "api.grpc.response.count",
497+
"status": "SCHEME_ERROR",
498+
"value": 1,
499+
},
500+
],
501+
}
502+
check_counters(slot_mon_port, expected_counters, "ydb_serverless")

0 commit comments

Comments
 (0)