Skip to content

Commit

Permalink
Merge pull request aya-rs#900 from catalin-h/log_init_from_program_id
Browse files Browse the repository at this point in the history
aya-log: allow re-attach and read previously created logs
  • Loading branch information
alessandrod authored Apr 25, 2024
2 parents fc2eb70 + 8830c0b commit e5d107d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
63 changes: 55 additions & 8 deletions aya-log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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)?;

Expand All @@ -134,8 +176,7 @@ impl EbpfLogger {
}
});
}

Ok(EbpfLogger {})
Ok(())
}
}

Expand Down Expand Up @@ -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<(), ()> {
Expand Down
6 changes: 6 additions & 0 deletions xtask/public-api/aya-log.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ pub aya_log::Error::InvalidOnlineCpu(std::io::error::Error)
pub aya_log::Error::MapError(aya::maps::MapError)
pub aya_log::Error::MapNotFound
pub aya_log::Error::PerfBufferError(aya::maps::perf::perf_buffer::PerfBufferError)
pub aya_log::Error::ProgramError(aya::programs::ProgramError)
pub aya_log::Error::ProgramNotFound
impl core::convert::From<aya::maps::MapError> for aya_log::Error
pub fn aya_log::Error::from(source: aya::maps::MapError) -> Self
impl core::convert::From<aya::maps::perf::perf_buffer::PerfBufferError> for aya_log::Error
pub fn aya_log::Error::from(source: aya::maps::perf::perf_buffer::PerfBufferError) -> Self
impl core::convert::From<aya::programs::ProgramError> for aya_log::Error
pub fn aya_log::Error::from(source: aya::programs::ProgramError) -> Self
impl core::error::Error for aya_log::Error
pub fn aya_log::Error::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
impl core::fmt::Debug for aya_log::Error
Expand Down Expand Up @@ -66,6 +70,8 @@ pub fn aya_log::DefaultFormatter::from(t: T) -> T
pub struct aya_log::EbpfLogger
impl aya_log::EbpfLogger
pub fn aya_log::EbpfLogger::init(bpf: &mut aya::bpf::Ebpf) -> core::result::Result<aya_log::EbpfLogger, aya_log::Error>
pub fn aya_log::EbpfLogger::init_from_id(program_id: u32) -> core::result::Result<aya_log::EbpfLogger, aya_log::Error>
pub fn aya_log::EbpfLogger::init_from_id_with_logger<T: log::Log + 'static>(program_id: u32, logger: T) -> core::result::Result<aya_log::EbpfLogger, aya_log::Error>
pub fn aya_log::EbpfLogger::init_with_logger<T: log::Log + 'static>(bpf: &mut aya::bpf::Ebpf, logger: T) -> core::result::Result<aya_log::EbpfLogger, aya_log::Error>
impl core::marker::Freeze for aya_log::EbpfLogger
impl core::marker::Send for aya_log::EbpfLogger
Expand Down

0 comments on commit e5d107d

Please sign in to comment.