Skip to content

Commit 7ae1a34

Browse files
committed
feat: add service executions metrics
1 parent 8547d75 commit 7ae1a34

6 files changed

Lines changed: 66 additions & 3 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Down migration: Remove metrics column and index from serviceExecutions table
2+
3+
-- Drop index first
4+
DROP INDEX IF EXISTS git."idx_serviceExecutions_metrics";
5+
6+
-- Drop column
7+
ALTER TABLE git."serviceExecutions"
8+
DROP COLUMN IF EXISTS metrics;
9+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Add metrics column to serviceExecutions table for storing service-specific execution metrics
2+
-- Examples: ai_cost for maintainer service, total_commits/bad_commits/total_activities for commit service
3+
4+
ALTER TABLE git."serviceExecutions"
5+
ADD COLUMN metrics JSONB DEFAULT '{}'::jsonb;
6+
7+
-- Create GIN index for efficient querying within JSONB data
8+
CREATE INDEX IF NOT EXISTS "idx_serviceExecutions_metrics"
9+
ON git."serviceExecutions" USING gin (metrics);
10+

services/apps/git_integration/src/crowdgit/database/crud.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,9 @@ async def save_service_execution(service_execution: ServiceExecution) -> None:
291291
sql_query = """
292292
INSERT INTO git."serviceExecutions" (
293293
"repoId", "operationType", "status", "errorCode",
294-
"errorMessage", "executionTimeSec"
294+
"errorMessage", "executionTimeSec", "metrics"
295295
)
296-
VALUES ($1, $2, $3, $4, $5, $6)
296+
VALUES ($1, $2, $3, $4, $5, $6, $7)
297297
"""
298298

299299
db_data = service_execution.to_db_dict()
@@ -306,6 +306,7 @@ async def save_service_execution(service_execution: ServiceExecution) -> None:
306306
db_data["errorCode"],
307307
db_data["errorMessage"],
308308
db_data["executionTimeSec"],
309+
db_data["metrics"],
309310
),
310311
)
311312
logger.debug(

services/apps/git_integration/src/crowdgit/models/service_execution.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from decimal import Decimal
22
from typing import Any
33

4+
import orjson
45
from pydantic import BaseModel, Field
56

67
from crowdgit.enums import ExecutionStatus, OperationType
@@ -15,6 +16,9 @@ class ServiceExecution(BaseModel):
1516
error_code: str | None = Field(None, description="Custom error code")
1617
error_message: str | None = Field(None, description="Detailed error message")
1718
execution_time_sec: Decimal = Field(..., description="Execution time in seconds")
19+
metrics: dict[str, Any] = Field(
20+
default_factory=dict, description="Service-specific execution metrics"
21+
)
1822

1923
def to_db_dict(self) -> dict[str, Any]:
2024
"""Convert create model to database dictionary"""
@@ -25,4 +29,5 @@ def to_db_dict(self) -> dict[str, Any]:
2529
"errorCode": self.error_code,
2630
"errorMessage": self.error_message,
2731
"executionTimeSec": self.execution_time_sec,
32+
"metrics": orjson.dumps(self.metrics).decode(),
2833
}

services/apps/git_integration/src/crowdgit/services/commit/commit_service.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ async def process_single_batch_commits(
112112
"execution_status": ExecutionStatus.SUCCESS,
113113
"error_code": None,
114114
"error_message": None,
115+
"total_commits": 0,
116+
"processed_commits": 0,
117+
"bad_commits": 0,
118+
"total_activities": 0,
115119
}
116120

117121
batch_start_time = time.time()
@@ -155,6 +159,12 @@ async def process_single_batch_commits(
155159
execution_time_sec=Decimal(
156160
str(round(self._metrics_context["total_execution_time"], 2))
157161
),
162+
metrics={
163+
"total_commits": self._metrics_context["total_commits"],
164+
"processed_commits": self._metrics_context["processed_commits"],
165+
"bad_commits": self._metrics_context["bad_commits"],
166+
"total_activities": self._metrics_context["total_activities"],
167+
},
158168
)
159169
await save_service_execution(service_execution)
160170
# Reset metrics context after saving
@@ -185,6 +195,12 @@ async def process_single_batch_commits(
185195
execution_time_sec=Decimal(
186196
str(round(self._metrics_context["total_execution_time"], 2))
187197
),
198+
metrics={
199+
"total_commits": self._metrics_context["total_commits"],
200+
"processed_commits": self._metrics_context["processed_commits"],
201+
"bad_commits": self._metrics_context["bad_commits"],
202+
"total_activities": self._metrics_context["total_activities"],
203+
},
188204
)
189205
await save_service_execution(service_execution)
190206
# Reset metrics context after saving
@@ -623,6 +639,12 @@ async def process_commits_chunk(
623639
f"Processed {processed_commits} commits, skipped {bad_commits} invalid commits in {repo_path}"
624640
)
625641

642+
# Update metrics context
643+
if self._metrics_context:
644+
self._metrics_context["processed_commits"] += processed_commits
645+
self._metrics_context["bad_commits"] += bad_commits
646+
self._metrics_context["total_activities"] += len(activities_db)
647+
626648
# Write activities to database and queue
627649
if activities_db:
628650
await asyncio.gather(
@@ -651,6 +673,11 @@ async def _process_activities_from_commits(
651673
gc.collect()
652674

653675
logger.info(f"Actual number of commits to be processed: {len(commit_texts)}")
676+
677+
# Update total_commits metric
678+
if self._metrics_context:
679+
self._metrics_context["total_commits"] += len(commit_texts)
680+
654681
if len(commit_texts) == 0:
655682
self.logger.info("No commits to be processed")
656683
return

services/apps/git_integration/src/crowdgit/services/maintainer/maintainer_service.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ async def process_maintainers(
439439
error_code = None
440440
error_message = None
441441
latest_maintainer_file = None
442+
ai_cost = 0.0
443+
maintainers_found = 0
442444

443445
try:
444446
owner, repo_name = parse_repo_url(batch_info.remote)
@@ -454,8 +456,10 @@ async def process_maintainers(
454456
self.logger.info(f"Starting maintainers processing for repo: {batch_info.remote}")
455457
maintainers = await self.extract_maintainers(batch_info.repo_path, owner, repo_name)
456458
latest_maintainer_file = maintainers.maintainer_file
459+
ai_cost = maintainers.total_cost
460+
maintainers_found = len(maintainers.maintainer_info)
457461
self.logger.info(
458-
f"Extracted {len(maintainers.maintainer_info)} maintainers from {latest_maintainer_file} file"
462+
f"Extracted {maintainers_found} maintainers from {latest_maintainer_file} file"
459463
)
460464
await self.save_maintainers(
461465
repository.id,
@@ -469,6 +473,9 @@ async def process_maintainers(
469473
error_code = (
470474
e.error_code.value if isinstance(e, CrowdGitError) else ErrorCode.UNKNOWN.value
471475
)
476+
# Capture AI cost even on error if it's a CrowdGitError with ai_cost
477+
if isinstance(e, CrowdGitError) and hasattr(e, "ai_cost"):
478+
ai_cost = e.ai_cost
472479

473480
self.logger.error(f"Maintainer processing failed: {error_message}")
474481
finally:
@@ -484,5 +491,9 @@ async def process_maintainers(
484491
error_code=error_code,
485492
error_message=error_message,
486493
execution_time_sec=execution_time,
494+
metrics={
495+
"ai_cost": ai_cost,
496+
"maintainers_found": maintainers_found,
497+
},
487498
)
488499
await save_service_execution(service_execution)

0 commit comments

Comments
 (0)