rapace_cell/
tracing_setup.rs

1//! Tracing integration for rapace cells.
2//!
3//! This module sets up tracing so that cell logs are forwarded to the host process
4//! via rapace-tracing. The host can also push filter updates to cells.
5
6use std::sync::Arc;
7
8use rapace::RpcSession;
9use rapace_tracing::{RapaceTracingLayer, SharedFilter, TracingConfigImpl, TracingConfigServer};
10use tracing_subscriber::layer::SubscriberExt;
11use tracing_subscriber::util::SubscriberInitExt;
12
13use crate::ServiceDispatch;
14
15/// Create a shared filter + TracingConfig service without installing the tracing layer.
16///
17/// This lets cells expose the TracingConfig RPC early (so the host can push filters)
18/// without emitting any tracing events until the cell decides to install the forwarding layer.
19pub fn create_tracing_config_service() -> (SharedFilter, TracingConfigService) {
20    let filter = SharedFilter::new();
21    let config_impl = TracingConfigImpl::new(filter.clone());
22    let config_server = TracingConfigServer::new(config_impl);
23    (filter, TracingConfigService::new(config_server))
24}
25
26/// Install the tracing layer that forwards spans/events to the host, using an existing filter.
27pub fn install_tracing_layer(session: Arc<RpcSession>, filter: SharedFilter) {
28    let rt = tokio::runtime::Handle::current();
29    let layer = RapaceTracingLayer::with_filter(session, rt, filter);
30    tracing_subscriber::registry().with(layer).init();
31}
32
33/// Initialize tracing for a cell, forwarding logs to the host.
34///
35/// Returns a TracingConfigService that should be added to the dispatcher
36/// so the host can push filter updates to this cell.
37pub fn init_cell_tracing(session: Arc<RpcSession>) -> TracingConfigService {
38    let (filter, service) = create_tracing_config_service();
39    install_tracing_layer(session, filter);
40    service
41}
42
43/// Wrapper around TracingConfigServer that implements ServiceDispatch.
44pub struct TracingConfigService(Arc<TracingConfigServer<TracingConfigImpl>>);
45
46impl TracingConfigService {
47    pub fn new(server: TracingConfigServer<TracingConfigImpl>) -> Self {
48        Self(Arc::new(server))
49    }
50}
51
52impl ServiceDispatch for TracingConfigService {
53    fn dispatch(
54        &self,
55        method_id: u32,
56        payload: &[u8],
57    ) -> std::pin::Pin<
58        Box<
59            dyn std::future::Future<Output = Result<rapace::Frame, rapace::RpcError>>
60                + Send
61                + 'static,
62        >,
63    > {
64        let server = self.0.clone();
65        let payload_owned = payload.to_vec();
66        Box::pin(async move { server.dispatch(method_id, &payload_owned).await })
67    }
68}