feat: add telemetry source identifier (#8918)
* add telemetry source * add source to provider trave
This commit is contained in:
committed by
Sarah Wooders
parent
15de765876
commit
2ee28c3264
@@ -0,0 +1,27 @@
|
|||||||
|
"""add source column to provider_traces
|
||||||
|
|
||||||
|
Revision ID: 82feb220a9b8
|
||||||
|
Revises: 539afa667cff
|
||||||
|
Create Date: 2026-01-18 21:09:59.529688
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "82feb220a9b8"
|
||||||
|
down_revision: Union[str, None] = "539afa667cff"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
op.add_column("provider_traces", sa.Column("source", sa.String(), nullable=True))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
op.drop_column("provider_traces", "source")
|
||||||
@@ -28,6 +28,9 @@ class ProviderTrace(SqlalchemyBase, OrganizationMixin):
|
|||||||
agent_tags: Mapped[Optional[list]] = mapped_column(JSON, nullable=True, doc="Tags associated with the agent for filtering")
|
agent_tags: Mapped[Optional[list]] = mapped_column(JSON, nullable=True, doc="Tags associated with the agent for filtering")
|
||||||
call_type: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="Type of call (agent_step, summarization, etc.)")
|
call_type: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="Type of call (agent_step, summarization, etc.)")
|
||||||
run_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="ID of the run this trace is associated with")
|
run_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="ID of the run this trace is associated with")
|
||||||
|
source: Mapped[Optional[str]] = mapped_column(
|
||||||
|
String, nullable=True, doc="Source service that generated this trace (memgpt-server, lettuce-py)"
|
||||||
|
)
|
||||||
|
|
||||||
# Relationships
|
# Relationships
|
||||||
organization: Mapped["Organization"] = relationship("Organization", lazy="selectin")
|
organization: Mapped["Organization"] = relationship("Organization", lazy="selectin")
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class ProviderTrace(BaseProviderTrace):
|
|||||||
agent_tags (list[str]): Tags associated with the agent for filtering.
|
agent_tags (list[str]): Tags associated with the agent for filtering.
|
||||||
call_type (str): Type of call (agent_step, summarization, etc.).
|
call_type (str): Type of call (agent_step, summarization, etc.).
|
||||||
run_id (str): ID of the run this trace is associated with.
|
run_id (str): ID of the run this trace is associated with.
|
||||||
|
source (str): Source service that generated this trace (memgpt-server, lettuce-py).
|
||||||
organization_id (str): The unique identifier of the organization.
|
organization_id (str): The unique identifier of the organization.
|
||||||
created_at (datetime): The timestamp when the object was created.
|
created_at (datetime): The timestamp when the object was created.
|
||||||
"""
|
"""
|
||||||
@@ -41,5 +42,6 @@ class ProviderTrace(BaseProviderTrace):
|
|||||||
agent_tags: Optional[list[str]] = Field(None, description="Tags associated with the agent for filtering")
|
agent_tags: Optional[list[str]] = Field(None, description="Tags associated with the agent for filtering")
|
||||||
call_type: Optional[str] = Field(None, description="Type of call (agent_step, summarization, etc.)")
|
call_type: Optional[str] = Field(None, description="Type of call (agent_step, summarization, etc.)")
|
||||||
run_id: Optional[str] = Field(None, description="ID of the run this trace is associated with")
|
run_id: Optional[str] = Field(None, description="ID of the run this trace is associated with")
|
||||||
|
source: Optional[str] = Field(None, description="Source service that generated this trace (memgpt-server, lettuce-py)")
|
||||||
|
|
||||||
created_at: datetime = Field(default_factory=get_utc_time, description="The timestamp when the object was created.")
|
created_at: datetime = Field(default_factory=get_utc_time, description="The timestamp when the object was created.")
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ class SocketProviderTraceBackend(ProviderTraceBackendClient):
|
|||||||
"step_id": provider_trace.step_id,
|
"step_id": provider_trace.step_id,
|
||||||
"tags": provider_trace.agent_tags or [],
|
"tags": provider_trace.agent_tags or [],
|
||||||
"type": provider_trace.call_type or "agent_step",
|
"type": provider_trace.call_type or "agent_step",
|
||||||
|
"source": provider_trace.source,
|
||||||
"request": request,
|
"request": request,
|
||||||
"response": response if not error else None,
|
"response": response if not error else None,
|
||||||
"error": error,
|
"error": error,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
|
|
||||||
from letta.helpers.singleton import singleton
|
from letta.helpers.singleton import singleton
|
||||||
from letta.log import get_logger
|
from letta.log import get_logger
|
||||||
@@ -6,6 +7,7 @@ from letta.otel.tracing import trace_method
|
|||||||
from letta.schemas.provider_trace import ProviderTrace
|
from letta.schemas.provider_trace import ProviderTrace
|
||||||
from letta.schemas.user import User as PydanticUser
|
from letta.schemas.user import User as PydanticUser
|
||||||
from letta.services.provider_trace_backends import get_provider_trace_backend, get_provider_trace_backends
|
from letta.services.provider_trace_backends import get_provider_trace_backend, get_provider_trace_backends
|
||||||
|
from letta.settings import telemetry_settings
|
||||||
from letta.utils import enforce_types
|
from letta.utils import enforce_types
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
@@ -51,6 +53,12 @@ class TelemetryManager:
|
|||||||
actor: PydanticUser,
|
actor: PydanticUser,
|
||||||
provider_trace: ProviderTrace,
|
provider_trace: ProviderTrace,
|
||||||
) -> ProviderTrace:
|
) -> ProviderTrace:
|
||||||
|
# Set source if not already set (use LETTA_TELEMETRY_SOURCE, fallback to DD_SERVICE)
|
||||||
|
if provider_trace.source is None:
|
||||||
|
source = telemetry_settings.source or os.environ.get("DD_SERVICE")
|
||||||
|
if source:
|
||||||
|
provider_trace = provider_trace.model_copy(update={"source": source})
|
||||||
|
|
||||||
# Write to all backends concurrently
|
# Write to all backends concurrently
|
||||||
tasks = [self._safe_create_async(backend, actor, provider_trace) for backend in self._backends]
|
tasks = [self._safe_create_async(backend, actor, provider_trace) for backend in self._backends]
|
||||||
results = await asyncio.gather(*tasks)
|
results = await asyncio.gather(*tasks)
|
||||||
@@ -77,6 +85,12 @@ class TelemetryManager:
|
|||||||
provider_trace: ProviderTrace,
|
provider_trace: ProviderTrace,
|
||||||
) -> ProviderTrace | None:
|
) -> ProviderTrace | None:
|
||||||
"""Synchronous version - writes to all backends."""
|
"""Synchronous version - writes to all backends."""
|
||||||
|
# Set source if not already set (use LETTA_TELEMETRY_SOURCE, fallback to DD_SERVICE)
|
||||||
|
if provider_trace.source is None:
|
||||||
|
source = telemetry_settings.source or os.environ.get("DD_SERVICE")
|
||||||
|
if source:
|
||||||
|
provider_trace = provider_trace.model_copy(update={"source": source})
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
for backend in self._backends:
|
for backend in self._backends:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -499,6 +499,10 @@ class TelemetrySettings(BaseSettings):
|
|||||||
validation_alias=AliasChoices("TELEMETRY_SOCKET", "socket_path"),
|
validation_alias=AliasChoices("TELEMETRY_SOCKET", "socket_path"),
|
||||||
description="Unix socket path for socket backend.",
|
description="Unix socket path for socket backend.",
|
||||||
)
|
)
|
||||||
|
source: str | None = Field(
|
||||||
|
default=None,
|
||||||
|
description="Source identifier for telemetry (memgpt-server, lettuce-py, etc.).",
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def provider_trace_backends(self) -> list[str]:
|
def provider_trace_backends(self) -> list[str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user