|
@@ -60,10 +60,12 @@ use std::{
|
|
|
const MAP_NAME: &str = "AYA_LOGS";
|
|
|
|
|
|
use aya::{
|
|
|
+ loaded_programs,
|
|
|
maps::{
|
|
|
perf::{AsyncPerfEventArray, Events, PerfBufferError},
|
|
|
- MapError,
|
|
|
+ Map, MapData, MapError, MapInfo,
|
|
|
},
|
|
|
+ programs::ProgramError,
|
|
|
util::online_cpus,
|
|
|
Ebpf, Pod,
|
|
|
};
|
|
@@ -112,12 +114,52 @@ impl EbpfLogger {
|
|
|
bpf: &mut Ebpf,
|
|
|
logger: T,
|
|
|
) -> Result<EbpfLogger, Error> {
|
|
|
- let logger = Arc::new(logger);
|
|
|
- let mut logs: AsyncPerfEventArray<_> = bpf
|
|
|
- .take_map(MAP_NAME)
|
|
|
- .ok_or(Error::MapNotFound)?
|
|
|
- .try_into()?;
|
|
|
+ let map = bpf.take_map(MAP_NAME).ok_or(Error::MapNotFound)?;
|
|
|
+ Self::read_logs_async(map, logger)?;
|
|
|
+ Ok(EbpfLogger {})
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Attaches to an existing `aya-log-ebpf` instance.
|
|
|
+ ///
|
|
|
+ /// Attaches to the logs produced by `program_id`. Can be used to read logs generated by a
|
|
|
+ /// pinned program. The log records will be written to the default logger. See [log::logger].
|
|
|
+ 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` instance and logs with the given logger.
|
|
|
+ ///
|
|
|
+ /// Attaches to the logs produced by `program_id`. Can be used to read logs generated by a
|
|
|
+ /// pinned program. The log records will be written to the given logger.
|
|
|
+ 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)? {
|
|
|
let mut buf = logs.open(cpu_id, None)?;
|
|
|
|
|
@@ -134,8 +176,7 @@ impl EbpfLogger {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
- Ok(EbpfLogger {})
|
|
|
+ Ok(())
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -374,6 +415,12 @@ pub enum Error {
|
|
|
|
|
|
#[error("invalid /sys/devices/system/cpu/online format")]
|
|
|
InvalidOnlineCpu(#[source] io::Error),
|
|
|
+
|
|
|
+ #[error("program not found")]
|
|
|
+ ProgramNotFound,
|
|
|
+
|
|
|
+ #[error(transparent)]
|
|
|
+ ProgramError(#[from] ProgramError),
|
|
|
}
|
|
|
|
|
|
fn log_buf(mut buf: &[u8], logger: &dyn Log) -> Result<(), ()> {
|