crabllm-proxy 0.0.11

HTTP proxy server for the crabllm LLM API gateway
Documentation
use crabllm_core::{
    BoxFuture, ChatCompletionRequest, ChatCompletionResponse, Error, Prefix, RequestContext,
};

pub struct RequestLogger;

impl RequestLogger {
    pub fn new(_config: &serde_json::Value) -> Result<Self, String> {
        Ok(Self)
    }
}

impl crabllm_core::Extension for RequestLogger {
    fn name(&self) -> &str {
        "logging"
    }

    fn prefix(&self) -> Prefix {
        *b"logg"
    }

    fn on_response(
        &self,
        ctx: &RequestContext,
        _request: &ChatCompletionRequest,
        response: &ChatCompletionResponse,
    ) -> BoxFuture<'_, ()> {
        let latency = ctx.started_at.elapsed();
        let (prompt, completion) = response
            .usage
            .as_ref()
            .map(|u| (u.prompt_tokens, u.completion_tokens))
            .unwrap_or((0, 0));

        tracing::info!(
            model = %ctx.model,
            provider = %ctx.provider,
            key = ctx.key_name.as_deref().unwrap_or("-"),
            stream = ctx.is_stream,
            latency_ms = latency.as_millis() as u64,
            prompt_tokens = prompt,
            completion_tokens = completion,
            "request completed"
        );

        Box::pin(async {})
    }

    fn on_error(&self, ctx: &RequestContext, error: &Error) -> BoxFuture<'_, ()> {
        let latency = ctx.started_at.elapsed();

        tracing::warn!(
            model = %ctx.model,
            provider = %ctx.provider,
            key = ctx.key_name.as_deref().unwrap_or("-"),
            stream = ctx.is_stream,
            latency_ms = latency.as_millis() as u64,
            error = %error,
            "request failed"
        );

        Box::pin(async {})
    }
}