Skip to content

Commit c23203f

Browse files
committed
RSPEED-2326: feat(observability): add inference event builder for rlsapi v1
Implement build_inference_event() matching rlsapi Splunk event format: - InferenceEventData dataclass for structured input - Handles auth_disabled case for org_id/system_id - Maps all fields from request data and configuration - Empty placeholders for RAG fields (not yet implemented) Signed-off-by: Major Hayden <major@redhat.com>
1 parent df39147 commit c23203f

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

src/observability/telemetry.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""Telemetry event builders for observability."""
2+
3+
from dataclasses import dataclass
4+
from typing import Any
5+
6+
from configuration import configuration
7+
8+
9+
@dataclass
10+
class InferenceEventData: # pylint: disable=too-many-instance-attributes
11+
"""Data required to build an inference telemetry event."""
12+
13+
question: str
14+
response: str
15+
inference_time: float
16+
model: str
17+
org_id: str
18+
system_id: str
19+
request_id: str
20+
cla_version: str
21+
system_os: str
22+
system_version: str
23+
system_arch: str
24+
25+
26+
def build_inference_event(data: InferenceEventData) -> dict[str, Any]:
27+
"""Build an inference telemetry event payload matching rlsapi format.
28+
29+
Args:
30+
data: The inference event data.
31+
32+
Returns:
33+
A dictionary matching the rlsapi Splunk event format.
34+
"""
35+
return {
36+
"question": data.question,
37+
"refined_questions": [],
38+
"context": "",
39+
"response": data.response,
40+
"inference_time": data.inference_time,
41+
"model": data.model,
42+
"deployment": configuration.deployment_environment,
43+
"org_id": data.org_id,
44+
"system_id": data.system_id,
45+
# Token counting not yet implemented in lightspeed-stack; rlsapi uses 0 as default
46+
"total_llm_tokens": 0,
47+
"request_id": data.request_id,
48+
"cla_version": data.cla_version,
49+
"system_os": data.system_os,
50+
"system_version": data.system_version,
51+
"system_arch": data.system_arch,
52+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""Unit tests for telemetry event builders."""
2+
3+
from unittest.mock import patch
4+
5+
import pytest
6+
7+
from observability.telemetry import InferenceEventData, build_inference_event
8+
9+
10+
@pytest.fixture(name="sample_event_data")
11+
def sample_event_data_fixture() -> InferenceEventData:
12+
"""Create sample inference event data for testing."""
13+
return InferenceEventData(
14+
question="How do I configure SSH?",
15+
response="To configure SSH, edit /etc/ssh/sshd_config...",
16+
inference_time=2.34,
17+
model="granite-3-8b-instruct",
18+
org_id="12345678",
19+
system_id="abc-def-123",
20+
request_id="req_xyz789",
21+
cla_version="CLA/0.4.0",
22+
system_os="RHEL",
23+
system_version="9.3",
24+
system_arch="x86_64",
25+
)
26+
27+
28+
def test_builds_event_with_all_fields(sample_event_data: InferenceEventData) -> None:
29+
"""Test event contains all required fields and placeholders."""
30+
with patch("observability.telemetry.configuration") as mock_config:
31+
mock_config.deployment_environment = "production"
32+
33+
event = build_inference_event(sample_event_data)
34+
35+
assert event["question"] == "How do I configure SSH?"
36+
assert event["response"] == "To configure SSH, edit /etc/ssh/sshd_config..."
37+
assert event["inference_time"] == 2.34
38+
assert event["model"] == "granite-3-8b-instruct"
39+
assert event["org_id"] == "12345678"
40+
assert event["system_id"] == "abc-def-123"
41+
assert event["request_id"] == "req_xyz789"
42+
assert event["cla_version"] == "CLA/0.4.0"
43+
assert event["system_os"] == "RHEL"
44+
assert event["system_version"] == "9.3"
45+
assert event["system_arch"] == "x86_64"
46+
assert event["deployment"] == "production"
47+
assert not event["refined_questions"]
48+
assert event["context"] == ""
49+
assert event["total_llm_tokens"] == 0
50+
51+
52+
def test_handles_auth_disabled_values() -> None:
53+
"""Test event handles auth_disabled placeholder values."""
54+
data = InferenceEventData(
55+
question="test",
56+
response="test",
57+
inference_time=1.0,
58+
model="test-model",
59+
org_id="auth_disabled",
60+
system_id="auth_disabled",
61+
request_id="req_123",
62+
cla_version="test/1.0",
63+
system_os="",
64+
system_version="",
65+
system_arch="",
66+
)
67+
68+
with patch("observability.telemetry.configuration") as mock_config:
69+
mock_config.deployment_environment = "test"
70+
71+
event = build_inference_event(data)
72+
73+
assert event["org_id"] == "auth_disabled"
74+
assert event["system_id"] == "auth_disabled"

0 commit comments

Comments
 (0)