Skip to main content

crabllm_proxy/ext/
logging.rs

1use crabllm_core::{BoxFuture, Error, Prefix, RequestContext};
2
3pub struct RequestLogger;
4
5impl RequestLogger {
6    pub fn new(_config: &serde_json::Value) -> Result<Self, String> {
7        Ok(Self)
8    }
9}
10
11impl crabllm_core::Extension for RequestLogger {
12    fn name(&self) -> &str {
13        "logging"
14    }
15
16    fn prefix(&self) -> Prefix {
17        *b"logg"
18    }
19
20    fn on_response(
21        &self,
22        ctx: &RequestContext,
23        _raw_request: &[u8],
24        raw_response: &[u8],
25    ) -> BoxFuture<'_, ()> {
26        let latency = ctx.started_at.elapsed();
27        let usage = crabllm_core::Usage::from(raw_response);
28
29        tracing::info!(
30            model = %ctx.model,
31            provider = %ctx.provider,
32            key = ctx.principal.as_deref().unwrap_or("-"),
33            stream = ctx.is_stream,
34            latency_ms = latency.as_millis() as u64,
35            prompt_tokens = usage.prompt_tokens(),
36            completion_tokens = usage.completion_tokens(),
37            "request completed"
38        );
39
40        Box::pin(async {})
41    }
42
43    fn on_error(&self, ctx: &RequestContext, error: &Error) -> BoxFuture<'_, ()> {
44        let latency = ctx.started_at.elapsed();
45
46        tracing::warn!(
47            model = %ctx.model,
48            provider = %ctx.provider,
49            key = ctx.principal.as_deref().unwrap_or("-"),
50            stream = ctx.is_stream,
51            latency_ms = latency.as_millis() as u64,
52            error = %error,
53            "request failed"
54        );
55
56        Box::pin(async {})
57    }
58}