Skip to content

Commit 1c8c671

Browse files
committed
feat: add resource retrieval telemetry tracking with new record type and helper function
1 parent 5b78dd8 commit 1c8c671

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

MCPForUnity/UnityMcpServer~/src/telemetry.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import sys
2121
import threading
2222
import time
23-
from typing import Optional, Dict, Any
23+
from typing import Any
2424
from urllib.parse import urlparse
2525
import uuid
2626

@@ -55,6 +55,7 @@ class RecordType(str, Enum):
5555
USAGE = "usage"
5656
LATENCY = "latency"
5757
FAILURE = "failure"
58+
RESOURCE_RETRIEVAL = "resource_retrieval"
5859
TOOL_EXECUTION = "tool_execution"
5960
UNITY_CONNECTION = "unity_connection"
6061
CLIENT_CONNECTION = "client_connection"
@@ -78,8 +79,8 @@ class TelemetryRecord:
7879
timestamp: float
7980
customer_uuid: str
8081
session_id: str
81-
data: Dict[str, Any]
82-
milestone: Optional[MilestoneType] = None
82+
data: dict[str, Any]
83+
milestone: MilestoneType | None = None
8384

8485

8586
class TelemetryConfig:
@@ -208,8 +209,8 @@ class TelemetryCollector:
208209

209210
def __init__(self):
210211
self.config = TelemetryConfig()
211-
self._customer_uuid: Optional[str] = None
212-
self._milestones: Dict[str, Dict[str, Any]] = {}
212+
self._customer_uuid: str | None = None
213+
self._milestones: dict[str, dict[str, Any]] = {}
213214
self._lock: threading.Lock = threading.Lock()
214215
# Bounded queue with single background worker (records only; no context propagation)
215216
self._queue: "queue.Queue[TelemetryRecord]" = queue.Queue(maxsize=1000)
@@ -262,7 +263,7 @@ def _save_milestones(self):
262263
except OSError as e:
263264
logger.warning(f"Failed to save milestones: {e}", exc_info=True)
264265

265-
def record_milestone(self, milestone: MilestoneType, data: Optional[Dict[str, Any]] = None) -> bool:
266+
def record_milestone(self, milestone: MilestoneType, data: dict[str, Any] | None = None) -> bool:
266267
"""Record a milestone event, returns True if this is the first occurrence"""
267268
if not self.config.enabled:
268269
return False
@@ -288,8 +289,8 @@ def record_milestone(self, milestone: MilestoneType, data: Optional[Dict[str, An
288289

289290
def record(self,
290291
record_type: RecordType,
291-
data: Dict[str, Any],
292-
milestone: Optional[MilestoneType] = None):
292+
data: dict[str, Any],
293+
milestone: MilestoneType | None = None):
293294
"""Record a telemetry event (async, non-blocking)"""
294295
if not self.config.enabled:
295296
return
@@ -393,7 +394,7 @@ def _send_telemetry(self, record: TelemetryRecord):
393394

394395

395396
# Global telemetry instance
396-
_telemetry_collector: Optional[TelemetryCollector] = None
397+
_telemetry_collector: TelemetryCollector | None = None
397398

398399

399400
def get_telemetry() -> TelemetryCollector:
@@ -405,18 +406,18 @@ def get_telemetry() -> TelemetryCollector:
405406

406407

407408
def record_telemetry(record_type: RecordType,
408-
data: Dict[str, Any],
409-
milestone: Optional[MilestoneType] = None):
409+
data: dict[str, Any],
410+
milestone: MilestoneType | None = None):
410411
"""Convenience function to record telemetry"""
411412
get_telemetry().record(record_type, data, milestone)
412413

413414

414-
def record_milestone(milestone: MilestoneType, data: Optional[Dict[str, Any]] = None) -> bool:
415+
def record_milestone(milestone: MilestoneType, data: dict[str, Any] | None = None) -> bool:
415416
"""Convenience function to record a milestone"""
416417
return get_telemetry().record_milestone(milestone, data)
417418

418419

419-
def record_tool_usage(tool_name: str, success: bool, duration_ms: float, error: Optional[str] = None, sub_action: Optional[str] = None):
420+
def record_tool_usage(tool_name: str, success: bool, duration_ms: float, error: str | None = None, sub_action: str | None = None):
420421
"""Record tool usage telemetry
421422
422423
Args:
@@ -445,7 +446,28 @@ def record_tool_usage(tool_name: str, success: bool, duration_ms: float, error:
445446
record_telemetry(RecordType.TOOL_EXECUTION, data)
446447

447448

448-
def record_latency(operation: str, duration_ms: float, metadata: Optional[Dict[str, Any]] = None):
449+
def record_resource_usage(resource_name: str, success: bool, duration_ms: float, error: str | None = None):
450+
"""Record resource usage telemetry
451+
452+
Args:
453+
resource_name: Name of the resource invoked (e.g., 'get_tests').
454+
success: Whether the resource completed successfully.
455+
duration_ms: Execution duration in milliseconds.
456+
error: Optional error message (truncated if present).
457+
"""
458+
data = {
459+
"resource_name": resource_name,
460+
"success": success,
461+
"duration_ms": round(duration_ms, 2)
462+
}
463+
464+
if error:
465+
data["error"] = str(error)[:200] # Limit error message length
466+
467+
record_telemetry(RecordType.RESOURCE_RETRIEVAL, data)
468+
469+
470+
def record_latency(operation: str, duration_ms: float, metadata: dict[str, Any] | None = None):
449471
"""Record latency telemetry"""
450472
data = {
451473
"operation": operation,
@@ -458,7 +480,7 @@ def record_latency(operation: str, duration_ms: float, metadata: Optional[Dict[s
458480
record_telemetry(RecordType.LATENCY, data)
459481

460482

461-
def record_failure(component: str, error: str, metadata: Optional[Dict[str, Any]] = None):
483+
def record_failure(component: str, error: str, metadata: dict[str, Any] | None = None):
462484
"""Record failure telemetry"""
463485
data = {
464486
"component": component,

MCPForUnity/UnityMcpServer~/src/telemetry_decorator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
from typing import Callable, Any
1010

11-
from telemetry import record_tool_usage, record_milestone, MilestoneType
11+
from telemetry import record_resource_usage, record_tool_usage, record_milestone, MilestoneType
1212

1313
_log = logging.getLogger("unity-mcp-telemetry")
1414
_decorator_log_count = 0

0 commit comments

Comments
 (0)