@@ -14,6 +14,7 @@ use pyo3::prelude::*;
1414use pyo3:: types:: { PyBytes , PyModule } ;
1515use shadi_memory:: { MemoryEntry as ShadiMemoryEntry , SqlCipherStore } ;
1616use shadi_sandbox:: { spawn_sandboxed, SandboxError , SandboxPolicy } ;
17+ use tracing:: { field, info_span} ;
1718
1819struct SessionFlagVerifier ;
1920
@@ -127,6 +128,8 @@ impl ShadiStore {
127128 }
128129
129130 fn put ( & self , session : & PySessionContext , key : & str , secret : & [ u8 ] ) -> PyResult < ( ) > {
131+ let span = info_span ! ( "shadi.secret.put" , secret. key = %key) ;
132+ let _guard = span. enter ( ) ;
130133 let ctx = session. to_context ( ) ;
131134 let guard = self . store . lock ( ) . map_err ( |_| PyRuntimeError :: new_err ( "lock poisoned" ) ) ?;
132135 let access = AgentSecretAccess :: new ( guard. as_ref ( ) , & self . verifier ) ;
@@ -141,6 +144,8 @@ impl ShadiStore {
141144 session : & PySessionContext ,
142145 key : & str ,
143146 ) -> PyResult < Bound < ' py , PyBytes > > {
147+ let span = info_span ! ( "shadi.secret.get" , secret. key = %key) ;
148+ let _guard = span. enter ( ) ;
144149 let ctx = session. to_context ( ) ;
145150 let guard = self . store . lock ( ) . map_err ( |_| PyRuntimeError :: new_err ( "lock poisoned" ) ) ?;
146151 let access = AgentSecretAccess :: new ( guard. as_ref ( ) , & self . verifier ) ;
@@ -150,6 +155,8 @@ impl ShadiStore {
150155 }
151156
152157 fn delete ( & self , session : & PySessionContext , key : & str ) -> PyResult < ( ) > {
158+ let span = info_span ! ( "shadi.secret.delete" , secret. key = %key) ;
159+ let _guard = span. enter ( ) ;
153160 let ctx = session. to_context ( ) ;
154161 let guard = self . store . lock ( ) . map_err ( |_| PyRuntimeError :: new_err ( "lock poisoned" ) ) ?;
155162 let access = AgentSecretAccess :: new ( guard. as_ref ( ) , & self . verifier ) ;
@@ -159,6 +166,8 @@ impl ShadiStore {
159166 }
160167
161168 fn list_keys ( & self , session : & PySessionContext ) -> PyResult < Vec < String > > {
169+ let span = info_span ! ( "shadi.secret.list_keys" ) ;
170+ let _guard = span. enter ( ) ;
162171 let ctx = session. to_context ( ) ;
163172 AgentSecretAccess :: require_verified ( & ctx) . map_err ( map_secret_error) ?;
164173 let guard = self . store . lock ( ) . map_err ( |_| PyRuntimeError :: new_err ( "lock poisoned" ) ) ?;
@@ -178,12 +187,16 @@ impl SqlCipherMemoryStore {
178187 }
179188
180189 fn put ( & self , scope : & str , entry_key : & str , payload : & str ) -> PyResult < i64 > {
190+ let span = info_span ! ( "shadi.memory.put" , memory. scope = %scope, memory. entry_key = %entry_key) ;
191+ let _guard = span. enter ( ) ;
181192 self . store
182193 . put ( scope, entry_key, payload)
183194 . map_err ( |err| PyRuntimeError :: new_err ( err. to_string ( ) ) )
184195 }
185196
186197 fn get_latest ( & self , scope : & str , entry_key : & str ) -> PyResult < Option < MemoryEntry > > {
198+ let span = info_span ! ( "shadi.memory.get_latest" , memory. scope = %scope, memory. entry_key = %entry_key) ;
199+ let _guard = span. enter ( ) ;
187200 let entry = self
188201 . store
189202 . get_latest ( scope, entry_key)
@@ -193,6 +206,13 @@ impl SqlCipherMemoryStore {
193206
194207 #[ pyo3( signature = ( query, scope=None , limit=10 ) ) ]
195208 fn search ( & self , query : & str , scope : Option < String > , limit : usize ) -> PyResult < Vec < MemoryEntry > > {
209+ let span = info_span ! (
210+ "shadi.memory.search" ,
211+ memory. query = %query,
212+ memory. scope = %scope. as_deref( ) . unwrap_or( "" ) ,
213+ memory. limit = limit as i64 ,
214+ ) ;
215+ let _guard = span. enter ( ) ;
196216 let entries = self
197217 . store
198218 . search ( scope. as_deref ( ) , query, limit)
@@ -205,6 +225,12 @@ impl SqlCipherMemoryStore {
205225
206226 #[ pyo3( signature = ( scope=None , limit=50 ) ) ]
207227 fn list ( & self , scope : Option < String > , limit : usize ) -> PyResult < Vec < MemoryEntry > > {
228+ let span = info_span ! (
229+ "shadi.memory.list" ,
230+ memory. scope = %scope. as_deref( ) . unwrap_or( "" ) ,
231+ memory. limit = limit as i64 ,
232+ ) ;
233+ let _guard = span. enter ( ) ;
208234 let entries = self
209235 . store
210236 . list ( scope. as_deref ( ) , limit)
@@ -216,6 +242,8 @@ impl SqlCipherMemoryStore {
216242 }
217243
218244 fn delete ( & self , scope : & str , entry_key : & str ) -> PyResult < usize > {
245+ let span = info_span ! ( "shadi.memory.delete" , memory. scope = %scope, memory. entry_key = %entry_key) ;
246+ let _guard = span. enter ( ) ;
219247 self . store
220248 . delete ( scope, entry_key)
221249 . map_err ( |err| PyRuntimeError :: new_err ( err. to_string ( ) ) )
@@ -286,6 +314,7 @@ impl PySessionContext {
286314
287315#[ pymodule]
288316fn shadi ( _py : Python < ' _ > , m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
317+ shadi_telemetry:: init ( "shadi-runtime" ) ;
289318 m. add_class :: < ShadiStore > ( ) ?;
290319 m. add_class :: < PySessionContext > ( ) ?;
291320 m. add_class :: < SqlCipherMemoryStore > ( ) ?;
@@ -325,6 +354,8 @@ fn inject_keychain_with_store(
325354 command : & mut Command ,
326355 mappings : & [ String ] ,
327356) -> Result < ( ) , String > {
357+ let span = info_span ! ( "shadi.secrets.inject" , secret. count = mappings. len( ) as i64 ) ;
358+ let _guard = span. enter ( ) ;
328359 for mapping in mappings {
329360 let ( key, env) = parse_key_env ( mapping) ?;
330361 let secret = store
@@ -361,6 +392,15 @@ fn run_sandboxed(
361392 return Err ( PyRuntimeError :: new_err ( "command must not be empty" ) ) ;
362393 }
363394
395+ let cwd_value = cwd. as_deref ( ) . unwrap_or ( "" ) ;
396+ let span = info_span ! (
397+ "shadi.sandbox.run" ,
398+ command = %command[ 0 ] ,
399+ cwd = %cwd_value,
400+ exit. code = field:: Empty ,
401+ ) ;
402+ let _guard = span. enter ( ) ;
403+
364404 let mut cmd = Command :: new ( & command[ 0 ] ) ;
365405 if command. len ( ) > 1 {
366406 cmd. args ( & command[ 1 ..] ) ;
@@ -381,6 +421,7 @@ fn run_sandboxed(
381421 let status = child
382422 . wait ( )
383423 . map_err ( |err| PyRuntimeError :: new_err ( err. to_string ( ) ) ) ?;
424+ span. record ( "exit.code" , & status. code ( ) . unwrap_or ( -1 ) ) ;
384425 Ok ( status. code ( ) . unwrap_or ( 1 ) )
385426}
386427
0 commit comments