wash_runtime/plugin/
wasi_logging.rs1use std::collections::HashSet;
29
30use anyhow::bail;
31
32const WASI_LOGGING_ID: &str = "wasi-logging";
33
34use crate::{
35 engine::{ctx::Ctx, workload::WorkloadComponent},
36 plugin::{HostPlugin, wasi_logging::bindings::wasi::logging::logging::Level},
37 wit::{WitInterface, WitWorld},
38};
39
40mod bindings {
41 wasmtime::component::bindgen!({
42 world: "logging",
43 trappable_imports: true,
44 async: true,
45 });
46}
47
48pub struct WasiLogging;
54
55impl bindings::wasi::logging::logging::Host for Ctx {
56 async fn log(&mut self, level: Level, context: String, message: String) -> anyhow::Result<()> {
57 match level {
58 Level::Critical => tracing::error!(id = &self.id, context, "{message}"),
59 Level::Error => tracing::error!(id = &self.id, context, "{message}"),
60 Level::Warn => tracing::warn!(id = &self.id, context, "{message}"),
61 Level::Info => tracing::info!(id = &self.id, context, "{message}"),
62 Level::Debug => tracing::debug!(id = &self.id, context, "{message}"),
63 Level::Trace => tracing::trace!(id = &self.id, context, "{message}"),
64 }
65 Ok(())
66 }
67}
68
69#[async_trait::async_trait]
70impl HostPlugin for WasiLogging {
71 fn id(&self) -> &'static str {
72 WASI_LOGGING_ID
73 }
74
75 fn world(&self) -> WitWorld {
76 WitWorld {
77 imports: HashSet::from([WitInterface::from("wasi:logging/logging@0.1.0-draft")]),
78 ..Default::default()
79 }
80 }
81
82 async fn on_component_bind(
83 &self,
84 workload_handle: &mut WorkloadComponent,
85 interfaces: std::collections::HashSet<crate::wit::WitInterface>,
86 ) -> anyhow::Result<()> {
87 let mut iter = interfaces.iter();
89 let Some(interface) = iter.next() else {
90 bail!("No interfaces provided; expected wasi:logging/logging");
91 };
92 if iter.next().is_some()
93 || interface.namespace != "wasi"
94 || interface.package != "logging"
95 || !interface.interfaces.contains("logging")
96 {
97 bail!(
98 "Expected exactly one interface: wasi:logging/logging, got: {:?}",
99 interfaces
100 );
101 }
102
103 bindings::wasi::logging::logging::add_to_linker(workload_handle.linker(), |ctx| ctx)?;
105
106 Ok(())
107 }
108}