@ -60,10 +60,12 @@ use std::{
const MAP_NAME : & str = "AYA_LOGS" ;
const MAP_NAME : & str = "AYA_LOGS" ;
use aya ::{
use aya ::{
loaded_programs ,
maps ::{
maps ::{
perf ::{ AsyncPerfEventArray , Events , PerfBufferError } ,
perf ::{ AsyncPerfEventArray , Events , PerfBufferError } ,
Map Error,
Map , MapData , Map Error, MapInfo ,
} ,
} ,
programs ::ProgramError ,
util ::online_cpus ,
util ::online_cpus ,
Ebpf , Pod ,
Ebpf , Pod ,
} ;
} ;
@ -112,12 +114,54 @@ impl EbpfLogger {
bpf : & mut Ebpf ,
bpf : & mut Ebpf ,
logger : T ,
logger : T ,
) -> Result < EbpfLogger , Error > {
) -> Result < EbpfLogger , Error > {
let logger = Arc ::new ( logger ) ;
let map = bpf . take_map ( MAP_NAME ) . ok_or ( Error ::MapNotFound ) ? ;
let mut logs : AsyncPerfEventArray < _ > = bpf
Self ::read_logs_async ( map , logger ) ? ;
. take_map ( MAP_NAME )
Ok ( EbpfLogger { } )
. ok_or ( Error ::MapNotFound ) ?
}
. try_into ( ) ? ;
/// Attaches to an existing `aya-log-ebpf` log created by a running ebpf
/// program identified by `program_id`. The log records will be written
/// to the default logger. See [log::logger].
/// It can be used to review the log for a pinned program after the user
/// application exits.
pub fn init_from_id ( program_id : u32 ) -> Result < EbpfLogger , Error > {
Self ::init_from_id_with_logger ( program_id , log ::logger ( ) )
}
/// Attaches to an existing `aya-log-ebpf` log created by a running ebpf
/// program identified by `program_id`. The log records will be written
/// to the user provided logger.
/// It can be used to review the log for a pinned program after the user
/// application exits.
pub fn init_from_id_with_logger < T : Log + ' static > (
program_id : u32 ,
logger : T ,
) -> Result < EbpfLogger , Error > {
let program_info = loaded_programs ( )
. filter_map ( | info | info . ok ( ) )
. find ( | info | info . id ( ) = = program_id )
. ok_or ( Error ::ProgramNotFound ) ? ;
let map = program_info
. map_ids ( )
. map_err ( Error ::ProgramError ) ?
. iter ( )
. filter_map ( | id | MapInfo ::from_id ( * id ) . ok ( ) )
. find ( | map_info | match map_info . name_as_str ( ) {
Some ( name ) = > name = = MAP_NAME ,
None = > false ,
} )
. ok_or ( Error ::MapNotFound ) ? ;
let map = MapData ::from_id ( map . id ( ) ) . map_err ( Error ::MapError ) ? ;
Self ::read_logs_async ( Map ::PerfEventArray ( map ) , logger ) ? ;
Ok ( EbpfLogger { } )
}
fn read_logs_async < T : Log + ' static > ( map : Map , logger : T ) -> Result < ( ) , Error > {
let mut logs : AsyncPerfEventArray < _ > = map . try_into ( ) ? ;
let logger = Arc ::new ( logger ) ;
for cpu_id in online_cpus ( ) . map_err ( Error ::InvalidOnlineCpu ) ? {
for cpu_id in online_cpus ( ) . map_err ( Error ::InvalidOnlineCpu ) ? {
let mut buf = logs . open ( cpu_id , None ) ? ;
let mut buf = logs . open ( cpu_id , None ) ? ;
@ -134,8 +178,7 @@ impl EbpfLogger {
}
}
} ) ;
} ) ;
}
}
Ok ( ( ) )
Ok ( EbpfLogger { } )
}
}
}
}
@ -374,6 +417,12 @@ pub enum Error {
#[ error( " invalid /sys/devices/system/cpu/online format " ) ]
#[ error( " invalid /sys/devices/system/cpu/online format " ) ]
InvalidOnlineCpu ( #[ source ] io ::Error ) ,
InvalidOnlineCpu ( #[ source ] io ::Error ) ,
#[ error( " program not found " ) ]
ProgramNotFound ,
#[ error(transparent) ]
ProgramError ( #[ from ] ProgramError ) ,
}
}
fn log_buf ( mut buf : & [ u8 ] , logger : & dyn Log ) -> Result < ( ) , ( ) > {
fn log_buf ( mut buf : & [ u8 ] , logger : & dyn Log ) -> Result < ( ) , ( ) > {