Skip to content

Commit 21bf3af

Browse files
committed
feat(controller): unified measurement model
1 parent 095c866 commit 21bf3af

14 files changed

Lines changed: 179 additions & 296 deletions

File tree

charts/controller/templates/controller-cronjob-daily.yaml

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,40 +39,4 @@ spec:
3939
args:
4040
- python /app/manage.py load_db_state_to_k8s
4141
{{- include "controller.envs" . | indent 12 }}
42-
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
43-
imagePullPolicy: {{.Values.pull_policy}}
44-
name: drycc-controller-measure-app
45-
command:
46-
- /bin/bash
47-
- -c
48-
args:
49-
- python -u /app/manage.py measure_app
50-
{{- include "controller.envs" . | indent 12 }}
51-
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
52-
imagePullPolicy: {{.Values.pull_policy}}
53-
name: drycc-controller-measure-config
54-
command:
55-
- /bin/bash
56-
- -c
57-
args:
58-
- python -u /app/manage.py measure_config
59-
{{- include "controller.envs" . | indent 12 }}
60-
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
61-
imagePullPolicy: {{.Values.pull_policy}}
62-
name: drycc-controller-measure-resources
63-
command:
64-
- /bin/bash
65-
- -c
66-
args:
67-
- python -u /app/manage.py measure_resources
68-
{{- include "controller.envs" . | indent 12 }}
69-
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
70-
imagePullPolicy: {{.Values.pull_policy}}
71-
name: drycc-controller-measure-volumes
72-
command:
73-
- /bin/bash
74-
- -c
75-
args:
76-
- python -u /app/manage.py measure_volumes
77-
{{- include "controller.envs" . | indent 12 }}
7842

charts/controller/templates/controller-cronjob-hourly.yaml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,28 @@ spec:
3232
containers:
3333
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
3434
imagePullPolicy: {{.Values.pull_policy}}
35-
name: drycc-controller-measure-app
35+
name: drycc-controller-measure-instance
3636
command:
3737
- /bin/bash
3838
- -c
3939
args:
40-
- python -u /app/manage.py measure_app
40+
- python -u /app/manage.py measure_instance
41+
{{- include "controller.envs" . | indent 12 }}
42+
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
43+
imagePullPolicy: {{.Values.pull_policy}}
44+
name: drycc-controller-measure-resources
45+
command:
46+
- /bin/bash
47+
- -c
48+
args:
49+
- python -u /app/manage.py measure_resources
50+
{{- include "controller.envs" . | indent 12 }}
51+
- image: {{.Values.image_registry}}/{{.Values.image_org}}/controller:{{.Values.image_tag}}
52+
imagePullPolicy: {{.Values.pull_policy}}
53+
name: drycc-controller-measure-volumes
54+
command:
55+
- /bin/bash
56+
- -c
57+
args:
58+
- python -u /app/manage.py measure_volumes
4159
{{- include "controller.envs" . | indent 12 }}
42-

rootfs/api/management/commands/measure_app.py

Lines changed: 0 additions & 67 deletions
This file was deleted.

rootfs/api/management/commands/measure_config.py

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import uuid
2+
import time
3+
import logging
4+
from django.utils import timezone
5+
from django.core.management.base import BaseCommand
6+
from django.conf import settings
7+
from api import influxdb
8+
from api.models import Config
9+
from api.tasks import send_measurements
10+
from api.utils import unit_to_bytes, unit_to_millicpu
11+
12+
logger = logging.getLogger(__name__)
13+
14+
15+
class Command(BaseCommand):
16+
"""Management command for push data to manager"""
17+
18+
def _to_cpu_measurement(self, config, record, timestamp):
19+
app_id = record["namespace"]
20+
owner_id = config.owner_id
21+
container_type = record["container_name"].replace(f"{app_id}-", "", 1)
22+
return {
23+
"app_id": app_id,
24+
"user_id": owner_id,
25+
"name": container_type,
26+
"type": "CPU",
27+
"unit": "MILLI",
28+
"usage": unit_to_millicpu(unit_to_millicpu(config.cpu.get(container_type))),
29+
"timestamp": "%f" % timestamp
30+
}
31+
32+
def _to_memory_measurement(self, config, record, timestamp):
33+
app_id = record["namespace"]
34+
owner_id = config.owner_id
35+
container_type = record["container_name"].replace(f"{app_id}-", "", 1)
36+
return {
37+
"app_id": app_id,
38+
"user_id": owner_id,
39+
"name": container_type,
40+
"type": "CPU",
41+
"unit": "MILLI",
42+
"usage": unit_to_bytes(self.memory.get(container_type)),
43+
"timestamp": "%f" % timestamp
44+
}
45+
46+
def _measure_networks(self, config_map, timestamp):
47+
stop = timestamp - (timestamp % 3600)
48+
start = stop - 3600
49+
networks = []
50+
for record in influxdb.query_network_flow(config_map.keys(), start, stop):
51+
app_id = record["namespace"]
52+
owner_id = config_map[app_id].owner_id
53+
networks.append({
54+
"app_id": app_id,
55+
"owner_id": owner_id,
56+
"name": record["pod_name"],
57+
"type": "NETWORK",
58+
"unit": "BYTES",
59+
"usage": record["rx_bytes"] + record["tx_bytes"],
60+
"timestamp": "%f" % timestamp
61+
})
62+
send_measurements.delay(networks)
63+
64+
def _measure_config(self, config_map, timestamp):
65+
stop = timestamp - (timestamp % 3600)
66+
start = stop - 3600
67+
measurement_map = {}
68+
for record in influxdb.query_container_count(config_map.keys(), start, stop):
69+
app_id = record["namespace"]
70+
cpu = self._to_cpu_measurement(config_map[app_id], record, timestamp)
71+
memory = self._to_memory_measurement(config_map[app_id], record, timestamp)
72+
key = f"{app_id}:cpu:{cpu['name']}"
73+
if key in measurement_map:
74+
measurement_map[key]["usage"] += cpu["usage"]
75+
else:
76+
measurement_map[key] = cpu
77+
key = f"{app_id}:memory:{cpu['name']}"
78+
if key in measurement_map:
79+
measurement_map[key]["usage"] += memory["usage"]
80+
else:
81+
measurement_map[key] = memory
82+
return measurement_map.values()
83+
84+
def handle(self, *args, **options):
85+
if settings.WORKFLOW_MANAGER_URL is not None:
86+
timestamp = time.time()
87+
task_id = uuid.uuid4().hex
88+
logger.info(f"pushing {task_id} limits to workflow_manager when {timezone.now()}")
89+
config_map = {}
90+
for config in Config.objects.all():
91+
config_map[config.app_d] = config
92+
if len(config_map) % 1000 == 0:
93+
send_measurements.delay(self._measure_config(config_map, timestamp))
94+
send_measurements.delay(self._measure_networks(config_map, timestamp))
95+
config_map = {}
96+
if len(config_map) > 0:
97+
send_measurements.delay(self._measure_config(config_map, timestamp))
98+
send_measurements.delay(self._measure_networks(config_map, timestamp))
99+
logger.info(f"pushed {task_id} limits to workflow_manager when {timezone.now()}")
100+
self.stdout.write("done")

rootfs/api/management/commands/measure_resources.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.core.management.base import BaseCommand
66
from django.conf import settings
77
from api.models import Resource
8-
from api.tasks import measure_resources
8+
from api.tasks import send_measurements
99

1010
logger = logging.getLogger(__name__)
1111

@@ -22,9 +22,9 @@ def handle(self, *args, **options):
2222
for resource in Resource.objects.all():
2323
resource_list.extend(resource.to_measurements(timestamp))
2424
if len(resource_list) % 1000 == 0:
25-
measure_resources.delay(resource_list)
25+
send_measurements.delay(resource_list)
2626
resource_list = []
2727
if len(resource_list) > 0:
28-
measure_resources.delay(resource_list)
28+
send_measurements.delay(resource_list)
2929
logger.info(f"pushed {task_id} resources to workflow_manager when {timezone.now()}")
3030
self.stdout.write("done")

rootfs/api/management/commands/measure_volumes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.core.management.base import BaseCommand
66
from django.conf import settings
77
from api.models import Volume
8-
from api.tasks import measure_volumes
8+
from api.tasks import send_measurements
99

1010
logger = logging.getLogger(__name__)
1111

@@ -22,9 +22,9 @@ def handle(self, *args, **options):
2222
for volume in Volume.objects.all():
2323
volume_list.extend(volume.to_measurements(timestamp))
2424
if len(volume_list) % 1000 == 0:
25-
measure_volumes.delay(volume_list)
25+
send_measurements.delay(volume_list)
2626
volume_list = []
2727
if len(volume_list) > 0:
28-
measure_volumes.delay(volume_list)
28+
send_measurements.delay(volume_list)
2929
logger.info(f"pushed {task_id} volumes to workflow_manager when {timezone.now()}")
3030
self.stdout.write("done")

0 commit comments

Comments
 (0)