Skip to content

Commit 638bfea

Browse files
author
benoit-cty
committed
Add CPU, GPU and RAM load to API
1 parent e38ba61 commit 638bfea

File tree

8 files changed

+110
-0
lines changed

8 files changed

+110
-0
lines changed

carbonserver/carbonserver/api/infra/database/sql_models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class Emission(Base):
2121
gpu_energy = Column(Float)
2222
ram_energy = Column(Float)
2323
energy_consumed = Column(Float)
24+
cpu_utilization_percent = Column(Float, nullable=True)
25+
gpu_utilization_percent = Column(Float, nullable=True)
26+
ram_utilization_percent = Column(Float, nullable=True)
2427
wue = Column(Float, nullable=False, default=0)
2528
run_id = Column(UUID(as_uuid=True), ForeignKey("runs.id", ondelete="CASCADE"))
2629
run = relationship("Run", back_populates="emissions")

carbonserver/carbonserver/api/infra/repositories/repository_emissions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ def add_emission(self, emission: EmissionCreate) -> UUID:
4141
gpu_energy=emission.gpu_energy,
4242
ram_energy=emission.ram_energy,
4343
energy_consumed=emission.energy_consumed,
44+
cpu_utilization_percent=emission.cpu_utilization_percent,
45+
gpu_utilization_percent=emission.gpu_utilization_percent,
46+
ram_utilization_percent=emission.ram_utilization_percent,
4447
wue=emission.wue,
4548
run_id=emission.run_id,
4649
)
@@ -105,6 +108,9 @@ def map_sql_to_schema(emission: sql_models.Emission) -> Emission:
105108
gpu_energy=emission.gpu_energy,
106109
ram_energy=emission.ram_energy,
107110
energy_consumed=emission.energy_consumed,
111+
cpu_utilization_percent=emission.cpu_utilization_percent,
112+
gpu_utilization_percent=emission.gpu_utilization_percent,
113+
ram_utilization_percent=emission.ram_utilization_percent,
108114
wue=emission.wue,
109115
run_id=emission.run_id,
110116
)

carbonserver/carbonserver/api/infra/repositories/repository_experiments.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ def get_project_detailed_sums_by_experiment(
135135
func.sum(SqlModelEmission.energy_consumed).label("energy_consumed"),
136136
func.sum(SqlModelEmission.duration).label("duration"),
137137
func.avg(SqlModelEmission.emissions_rate).label("emissions_rate"),
138+
func.avg(SqlModelEmission.cpu_utilization_percent).label(
139+
"cpu_utilization_percent"
140+
),
141+
func.avg(SqlModelEmission.gpu_utilization_percent).label(
142+
"gpu_utilization_percent"
143+
),
144+
func.avg(SqlModelEmission.ram_utilization_percent).label(
145+
"ram_utilization_percent"
146+
),
138147
func.count(SqlModelEmission.emissions_rate).label(
139148
"emissions_count"
140149
),

carbonserver/carbonserver/api/infra/repositories/repository_organizations.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ def get_organization_detailed_sums(
116116
func.sum(SqlModelEmission.energy_consumed).label("energy_consumed"),
117117
func.sum(SqlModelEmission.duration).label("duration"),
118118
func.avg(SqlModelEmission.emissions_rate).label("emissions_rate"),
119+
func.avg(SqlModelEmission.cpu_utilization_percent).label(
120+
"cpu_utilization_percent"
121+
),
122+
func.avg(SqlModelEmission.gpu_utilization_percent).label(
123+
"gpu_utilization_percent"
124+
),
125+
func.avg(SqlModelEmission.ram_utilization_percent).label(
126+
"ram_utilization_percent"
127+
),
119128
func.count(SqlModelEmission.emissions_rate).label(
120129
"emissions_count"
121130
),

carbonserver/carbonserver/api/infra/repositories/repository_projects.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ def get_project_detailed_sums(
130130
func.sum(SqlModelEmission.energy_consumed).label("energy_consumed"),
131131
func.sum(SqlModelEmission.duration).label("duration"),
132132
func.avg(SqlModelEmission.emissions_rate).label("emissions_rate"),
133+
func.avg(SqlModelEmission.cpu_utilization_percent).label(
134+
"cpu_utilization_percent"
135+
),
136+
func.avg(SqlModelEmission.gpu_utilization_percent).label(
137+
"gpu_utilization_percent"
138+
),
139+
func.avg(SqlModelEmission.ram_utilization_percent).label(
140+
"ram_utilization_percent"
141+
),
133142
func.count(SqlModelEmission.emissions_rate).label(
134143
"emissions_count"
135144
),

carbonserver/carbonserver/api/infra/repositories/repository_runs.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ def get_experiment_detailed_sums_by_run(
144144
func.sum(SqlModelEmission.energy_consumed).label("energy_consumed"),
145145
func.sum(SqlModelEmission.duration).label("duration"),
146146
func.avg(SqlModelEmission.emissions_rate).label("emissions_rate"),
147+
func.avg(SqlModelEmission.cpu_utilization_percent).label(
148+
"cpu_utilization_percent"
149+
),
150+
func.avg(SqlModelEmission.gpu_utilization_percent).label(
151+
"gpu_utilization_percent"
152+
),
153+
func.avg(SqlModelEmission.ram_utilization_percent).label(
154+
"ram_utilization_percent"
155+
),
147156
func.count(SqlModelEmission.emissions_rate).label(
148157
"emissions_count"
149158
),

carbonserver/carbonserver/api/schemas.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ class EmissionBase(BaseModel):
8787
ram_energy: Optional[float] = Field(
8888
..., ge=0, description="The ram_energy must be greater than zero"
8989
)
90+
cpu_utilization_percent: Optional[float] = Field(
91+
None, ge=0, le=100, description="The CPU utilization must be between 0 and 100"
92+
)
93+
gpu_utilization_percent: Optional[float] = Field(
94+
None, ge=0, le=100, description="The GPU utilization must be between 0 and 100"
95+
)
96+
ram_utilization_percent: Optional[float] = Field(
97+
None, ge=0, le=100, description="The RAM utilization must be between 0 and 100"
98+
)
9099
wue: Optional[float] = Field(
91100
default=0,
92101
ge=0,
@@ -183,6 +192,9 @@ class RunReport(RunBase):
183192
duration: float
184193
emissions_rate: float
185194
emissions_count: int
195+
cpu_utilization_percent: Optional[float] = None
196+
gpu_utilization_percent: Optional[float] = None
197+
ram_utilization_percent: Optional[float] = None
186198

187199

188200
class ExperimentBase(BaseModel):
@@ -246,6 +258,9 @@ class ExperimentReport(ExperimentBase):
246258
duration: int
247259
emissions_rate: float
248260
emissions_count: int
261+
cpu_utilization_percent: Optional[float] = None
262+
gpu_utilization_percent: Optional[float] = None
263+
ram_utilization_percent: Optional[float] = None
249264

250265
class Config:
251266
schema_extra = {
@@ -377,6 +392,9 @@ class ProjectReport(ProjectBase):
377392
duration: int
378393
emissions_rate: float
379394
emissions_count: int
395+
cpu_utilization_percent: Optional[float] = None
396+
gpu_utilization_percent: Optional[float] = None
397+
ram_utilization_percent: Optional[float] = None
380398

381399

382400
class OrganizationBase(BaseModel):
@@ -420,6 +438,9 @@ class OrganizationReport(OrganizationBase):
420438
duration: int
421439
emissions_rate: float
422440
emissions_count: int
441+
cpu_utilization_percent: Optional[float] = None
442+
gpu_utilization_percent: Optional[float] = None
443+
ram_utilization_percent: Optional[float] = None
423444

424445

425446
class Membership(BaseModel):
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""add_utilization_metrics_to_emissions
2+
3+
Revision ID: 20251119_add_utilization
4+
Revises: 202501_f3a10
5+
Create Date: 2025-11-19 18:52:00.000000
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "20251119_add_utilization"
14+
down_revision = "202501_f3a10"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
"""
21+
Add CPU, GPU, and RAM utilization percentage fields to emissions table.
22+
These fields track the average utilization of resources during emission tracking.
23+
"""
24+
op.add_column(
25+
"emissions",
26+
sa.Column("cpu_utilization_percent", sa.Float, nullable=True),
27+
)
28+
op.add_column(
29+
"emissions",
30+
sa.Column("gpu_utilization_percent", sa.Float, nullable=True),
31+
)
32+
op.add_column(
33+
"emissions",
34+
sa.Column("ram_utilization_percent", sa.Float, nullable=True),
35+
)
36+
37+
38+
def downgrade():
39+
"""
40+
Remove CPU, GPU, and RAM utilization percentage fields from emissions table.
41+
"""
42+
op.drop_column("emissions", "ram_utilization_percent")
43+
op.drop_column("emissions", "gpu_utilization_percent")
44+
op.drop_column("emissions", "cpu_utilization_percent")

0 commit comments

Comments
 (0)