|
import traceback |
|
|
|
from litellm._logging import verbose_logger |
|
|
|
|
|
class TraceloopLogger: |
|
""" |
|
WARNING: DEPRECATED |
|
Use the OpenTelemetry standard integration instead |
|
""" |
|
|
|
def __init__(self): |
|
try: |
|
from traceloop.sdk import Traceloop |
|
from traceloop.sdk.tracing.tracing import TracerWrapper |
|
except ModuleNotFoundError as e: |
|
verbose_logger.error( |
|
f"Traceloop not installed, try running 'pip install traceloop-sdk' to fix this error: {e}\n{traceback.format_exc()}" |
|
) |
|
raise e |
|
|
|
Traceloop.init( |
|
app_name="Litellm-Server", |
|
disable_batch=True, |
|
) |
|
self.tracer_wrapper = TracerWrapper() |
|
|
|
def log_event( |
|
self, |
|
kwargs, |
|
response_obj, |
|
start_time, |
|
end_time, |
|
user_id, |
|
print_verbose, |
|
level="DEFAULT", |
|
status_message=None, |
|
): |
|
from opentelemetry.semconv.ai import SpanAttributes |
|
from opentelemetry.trace import SpanKind, Status, StatusCode |
|
|
|
try: |
|
print_verbose( |
|
f"Traceloop Logging - Enters logging function for model {kwargs}" |
|
) |
|
|
|
tracer = self.tracer_wrapper.get_tracer() |
|
|
|
optional_params = kwargs.get("optional_params", {}) |
|
start_time = int(start_time.timestamp()) |
|
end_time = int(end_time.timestamp()) |
|
span = tracer.start_span( |
|
"litellm.completion", kind=SpanKind.CLIENT, start_time=start_time |
|
) |
|
|
|
if span.is_recording(): |
|
span.set_attribute( |
|
SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model") |
|
) |
|
if "stop" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_CHAT_STOP_SEQUENCES, |
|
optional_params.get("stop"), |
|
) |
|
if "frequency_penalty" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_FREQUENCY_PENALTY, |
|
optional_params.get("frequency_penalty"), |
|
) |
|
if "presence_penalty" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_PRESENCE_PENALTY, |
|
optional_params.get("presence_penalty"), |
|
) |
|
if "top_p" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_REQUEST_TOP_P, optional_params.get("top_p") |
|
) |
|
if "tools" in optional_params or "functions" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_REQUEST_FUNCTIONS, |
|
optional_params.get("tools", optional_params.get("functions")), |
|
) |
|
if "user" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_USER, optional_params.get("user") |
|
) |
|
if "max_tokens" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_REQUEST_MAX_TOKENS, |
|
kwargs.get("max_tokens"), |
|
) |
|
if "temperature" in optional_params: |
|
span.set_attribute( |
|
SpanAttributes.LLM_REQUEST_TEMPERATURE, |
|
kwargs.get("temperature"), |
|
) |
|
|
|
for idx, prompt in enumerate(kwargs.get("messages")): |
|
span.set_attribute( |
|
f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", |
|
prompt.get("role"), |
|
) |
|
span.set_attribute( |
|
f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", |
|
prompt.get("content"), |
|
) |
|
|
|
span.set_attribute( |
|
SpanAttributes.LLM_RESPONSE_MODEL, response_obj.get("model") |
|
) |
|
usage = response_obj.get("usage") |
|
if usage: |
|
span.set_attribute( |
|
SpanAttributes.LLM_USAGE_TOTAL_TOKENS, |
|
usage.get("total_tokens"), |
|
) |
|
span.set_attribute( |
|
SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, |
|
usage.get("completion_tokens"), |
|
) |
|
span.set_attribute( |
|
SpanAttributes.LLM_USAGE_PROMPT_TOKENS, |
|
usage.get("prompt_tokens"), |
|
) |
|
|
|
for idx, choice in enumerate(response_obj.get("choices")): |
|
span.set_attribute( |
|
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.finish_reason", |
|
choice.get("finish_reason"), |
|
) |
|
span.set_attribute( |
|
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role", |
|
choice.get("message").get("role"), |
|
) |
|
span.set_attribute( |
|
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content", |
|
choice.get("message").get("content"), |
|
) |
|
|
|
if ( |
|
level == "ERROR" |
|
and status_message is not None |
|
and isinstance(status_message, str) |
|
): |
|
span.record_exception(Exception(status_message)) |
|
span.set_status(Status(StatusCode.ERROR, status_message)) |
|
|
|
span.end(end_time) |
|
|
|
except Exception as e: |
|
print_verbose(f"Traceloop Layer Error - {e}") |
|
|