diff --git a/aya-log-common/src/lib.rs b/aya-log-common/src/lib.rs index 7c5225eb..ab69d628 100644 --- a/aya-log-common/src/lib.rs +++ b/aya-log-common/src/lib.rs @@ -2,13 +2,11 @@ use core::{ net::{IpAddr, Ipv4Addr, Ipv6Addr}, - num::{NonZeroUsize, TryFromIntError}, + num::TryFromIntError, }; use num_enum::IntoPrimitive; -pub const LOG_FIELDS: usize = 6; - pub type LogValueLength = u16; #[repr(u8)] @@ -93,8 +91,8 @@ impl UpperMacFormatter for [u8; 6] {} #[repr(u8)] #[derive(Copy, Clone, Debug, IntoPrimitive)] -pub enum RecordField { - Target = 1, +pub enum RecordFieldKind { + Target, Level, Module, File, @@ -106,7 +104,7 @@ pub enum RecordField { /// programs to userspace. #[repr(u8)] #[derive(Copy, Clone, Debug, IntoPrimitive)] -pub enum Argument { +pub enum ArgumentKind { DisplayHint, I8, @@ -158,172 +156,207 @@ pub enum DisplayHint { UpperMac, } -// Must be inlined, else the BPF backend emits: -// -// llvm: :0:0: in function _ZN14aya_log_common5write17hc9ed05433e23a663E { i64, i64 } (i8, ptr, i64, ptr, i64): only integer returns supported -#[inline(always)] -pub(crate) fn write(tag: u8, value: &[u8], buf: &mut [u8]) -> Option { - // TODO(https://github.com/rust-lang/rust-clippy/issues/14112): Remove this allowance when the - // lint behaves more sensibly. - #[expect(clippy::manual_ok_err)] - let wire_len: LogValueLength = match value.len().try_into() { - Ok(wire_len) => Some(wire_len), - Err(TryFromIntError { .. }) => None, - }?; - let mut size = 0; - for slice in [&[tag][..], &wire_len.to_ne_bytes()[..], value] { - let buf = buf.get_mut(size..)?; - let buf = buf.get_mut(..slice.len())?; - buf.copy_from_slice(slice); - size += slice.len(); - } - NonZeroUsize::new(size) -} - -pub trait WriteToBuf { - fn write(self, buf: &mut [u8]) -> Option; +pub trait Argument { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>); } -macro_rules! impl_write_to_buf { - ($type:ident, $arg_type:expr) => { - impl WriteToBuf for $type { - // This need not be inlined because the return value is Option where N is - // mem::size_of<$type>, which is a compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - write($arg_type.into(), &self.to_ne_bytes(), buf) +macro_rules! impl_argument { + ($self:ident, $arg_type:expr) => { + impl Argument for $self { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + ($arg_type, self.to_ne_bytes()) } } }; } -impl_write_to_buf!(i8, Argument::I8); -impl_write_to_buf!(i16, Argument::I16); -impl_write_to_buf!(i32, Argument::I32); -impl_write_to_buf!(i64, Argument::I64); -impl_write_to_buf!(isize, Argument::Isize); +impl_argument!(i8, ArgumentKind::I8); +impl_argument!(i16, ArgumentKind::I16); +impl_argument!(i32, ArgumentKind::I32); +impl_argument!(i64, ArgumentKind::I64); +impl_argument!(isize, ArgumentKind::Isize); + +impl_argument!(u8, ArgumentKind::U8); +impl_argument!(u16, ArgumentKind::U16); +impl_argument!(u32, ArgumentKind::U32); +impl_argument!(u64, ArgumentKind::U64); +impl_argument!(usize, ArgumentKind::Usize); -impl_write_to_buf!(u8, Argument::U8); -impl_write_to_buf!(u16, Argument::U16); -impl_write_to_buf!(u32, Argument::U32); -impl_write_to_buf!(u64, Argument::U64); -impl_write_to_buf!(usize, Argument::Usize); +impl_argument!(f32, ArgumentKind::F32); +impl_argument!(f64, ArgumentKind::F64); -impl_write_to_buf!(f32, Argument::F32); -impl_write_to_buf!(f64, Argument::F64); +enum Either { + Left(L), + Right(R), +} -impl WriteToBuf for IpAddr { - fn write(self, buf: &mut [u8]) -> Option { +impl AsRef<[u8]> for Either +where + L: AsRef<[u8]>, + R: AsRef<[u8]>, +{ + fn as_ref(&self) -> &[u8] { match self { - IpAddr::V4(ipv4_addr) => write(Argument::Ipv4Addr.into(), &ipv4_addr.octets(), buf), - IpAddr::V6(ipv6_addr) => write(Argument::Ipv6Addr.into(), &ipv6_addr.octets(), buf), + Either::Left(l) => l.as_ref(), + Either::Right(r) => r.as_ref(), } } } -impl WriteToBuf for Ipv4Addr { - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::Ipv4Addr.into(), &self.octets(), buf) +impl Argument for IpAddr { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + match self { + IpAddr::V4(ipv4_addr) => { + let (kind, value) = ipv4_addr.as_argument(); + (kind, Either::Left(value)) + } + IpAddr::V6(ipv6_addr) => { + let (kind, value) = ipv6_addr.as_argument(); + (kind, Either::Right(value)) + } + } } } -impl WriteToBuf for [u8; 4] { - // This need not be inlined because the return value is Option where N is 16, which is a - // compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::ArrU8Len4.into(), &self, buf) +impl Argument for Ipv4Addr { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::Ipv4Addr, self.octets()) } } -impl WriteToBuf for Ipv6Addr { - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::Ipv6Addr.into(), &self.octets(), buf) +impl Argument for [u8; 4] { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::ArrU8Len4, self) } } -impl WriteToBuf for [u8; 16] { - // This need not be inlined because the return value is Option where N is 16, which is a - // compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::ArrU8Len16.into(), &self, buf) +impl Argument for Ipv6Addr { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::Ipv6Addr, self.octets()) } } -impl WriteToBuf for [u16; 8] { - // This need not be inlined because the return value is Option where N is 16, which is a - // compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - let bytes = unsafe { core::mem::transmute::<[u16; 8], [u8; 16]>(self) }; - write(Argument::ArrU16Len8.into(), &bytes, buf) +impl Argument for [u8; 16] { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::ArrU8Len16, self) } } -impl WriteToBuf for [u8; 6] { - // This need not be inlined because the return value is Option where N is 6, which is a - // compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::ArrU8Len6.into(), &self, buf) +impl Argument for [u16; 8] { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + let bytes = unsafe { core::mem::transmute::<&[u16; 8], &[u8; 16]>(self) }; + (ArgumentKind::ArrU16Len8, bytes) } } -impl WriteToBuf for &[u8] { - // Must be inlined, else the BPF backend emits: - // - // llvm: :0:0: in function _ZN63_$LT$$RF$$u5b$u8$u5d$$u20$as$u20$aya_log_common..WriteToBuf$GT$5write17h08f30a45f7b9f09dE { i64, i64 } (ptr, i64, ptr, i64): only integer returns supported - #[inline(always)] - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::Bytes.into(), self, buf) +impl Argument for [u8; 6] { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::ArrU8Len6, self) } } -impl WriteToBuf for &str { - // Must be inlined, else the BPF backend emits: - // - // llvm: :0:0: in function _ZN54_$LT$$RF$str$u20$as$u20$aya_log_common..WriteToBuf$GT$5write17h7e2d1ccaa758e2b5E { i64, i64 } (ptr, i64, ptr, i64): only integer returns supported - #[inline(always)] - fn write(self, buf: &mut [u8]) -> Option { - write(Argument::Str.into(), self.as_bytes(), buf) +impl Argument for &[u8] { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::Bytes, self) } } -impl WriteToBuf for DisplayHint { - // This need not be inlined because the return value is Option where N is 1, which is a - // compile-time constant. - #[inline(never)] - fn write(self, buf: &mut [u8]) -> Option { - let v: u8 = self.into(); - write(Argument::DisplayHint.into(), &v.to_ne_bytes(), buf) +impl Argument for &str { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + (ArgumentKind::Str, self.as_bytes()) + } +} + +impl Argument for DisplayHint { + fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) { + let v: u8 = (*self).into(); + (ArgumentKind::DisplayHint, v.to_ne_bytes()) + } +} + +fn wire_len(value: &[u8]) -> Option<[u8; 2]> { + match LogValueLength::try_from(value.len()) { + Ok(wire_len) => Some(wire_len.to_ne_bytes()), + Err(TryFromIntError { .. }) => None, + } +} + +#[doc(hidden)] +pub struct Field([u8; 1], [u8; 2], T); + +impl> Field { + pub fn new(kind: impl Into, value: T) -> Option { + let wire_len = wire_len(value.as_ref())?; + Some(Self([kind.into()], wire_len, value)) + } + + pub fn with_bytes(&self, op: &mut impl FnMut(&[u8]) -> Option<()>) -> Option<()> { + let Self(kind, wire_len, value) = self; + op(&kind[..])?; + op(&wire_len[..])?; + op(value.as_ref())?; + Some(()) } } #[doc(hidden)] -#[inline(always)] // This function takes too many arguments to not be inlined. -pub fn write_record_header( - buf: &mut [u8], - target: &str, - level: Level, - module: &str, - file: &str, - line: u32, - num_args: usize, -) -> Option { - let level: u8 = level.into(); - let mut size = 0; - for (tag, value) in [ - (RecordField::Target, target.as_bytes()), - (RecordField::Level, &level.to_ne_bytes()), - (RecordField::Module, module.as_bytes()), - (RecordField::File, file.as_bytes()), - (RecordField::Line, &line.to_ne_bytes()), - (RecordField::NumArgs, &num_args.to_ne_bytes()), - ] { - let buf = buf.get_mut(size..)?; - let len = write(tag.into(), value, buf)?; - size += len.get(); +pub struct Header<'a> { + target: Field<&'a [u8]>, + level: Field<[u8; 1]>, + module: Field<&'a [u8]>, + file: Field<&'a [u8]>, + line: Field<[u8; 4]>, + num_args: Field<[u8; 4]>, +} + +impl<'a> Header<'a> { + pub fn new( + target: &'a str, + level: Level, + module: &'a str, + file: &'a str, + line: u32, + num_args: u32, + ) -> Option { + let target = target.as_bytes(); + let level: u8 = level.into(); + let level = level.to_ne_bytes(); + let module = module.as_bytes(); + let file = file.as_bytes(); + let line = line.to_ne_bytes(); + let num_args = num_args.to_ne_bytes(); + let target = Field::new(RecordFieldKind::Target, target)?; + let level = Field::new(RecordFieldKind::Level, level)?; + let module = Field::new(RecordFieldKind::Module, module)?; + let file = Field::new(RecordFieldKind::File, file)?; + let line = Field::new(RecordFieldKind::Line, line)?; + let num_args = Field::new(RecordFieldKind::NumArgs, num_args)?; + + Some(Self { + target, + level, + module, + file, + line, + num_args, + }) + } + + pub fn with_bytes(&self, op: &mut impl FnMut(&[u8]) -> Option<()>) -> Option<()> { + let Self { + target, + level, + module, + file, + line, + num_args, + } = self; + target.with_bytes(op)?; + level.with_bytes(op)?; + module.with_bytes(op)?; + file.with_bytes(op)?; + line.with_bytes(op)?; + num_args.with_bytes(op)?; + Some(()) } - NonZeroUsize::new(size) } diff --git a/aya-log-ebpf-macros/src/expand.rs b/aya-log-ebpf-macros/src/expand.rs index 890ffdc7..1dd0d5f2 100644 --- a/aya-log-ebpf-macros/src/expand.rs +++ b/aya-log-ebpf-macros/src/expand.rs @@ -1,5 +1,5 @@ use aya_log_common::DisplayHint; -use aya_log_parser::{Fragment, parse}; +use aya_log_parser::{Fragment, Parameter, parse}; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote; use syn::{ @@ -105,12 +105,12 @@ pub(crate) fn log(args: LogArgs, level: Option) -> Result values.push(quote!(#s)), - Fragment::Parameter(p) => { - let arg = match formatting_args { - Some(ref args) => args[arg_i].clone(), + Fragment::Parameter(Parameter { hint }) => { + let arg = match &formatting_args { + Some(args) => &args[arg_i], None => return Err(Error::new(format_string.span(), "no arguments provided")), }; - let (hint, formatter) = match p.hint { + let (hint, formatter) = match hint { DisplayHint::Default => { (quote!(DisplayHint::Default), quote!(DefaultFormatter)) } @@ -144,41 +144,78 @@ pub(crate) fn log(args: LogArgs, level: Option) -> Result = (0..values.len()) + .map(|arg_i| quote::format_ident!("__arg{arg_i}")) + .collect(); + let num_args = values.len(); - let values_iter = values.iter(); - let buf = Ident::new("buf", Span::mixed_site()); - let size = Ident::new("size", Span::mixed_site()); - let len = Ident::new("len", Span::mixed_site()); - let record = Ident::new("record", Span::mixed_site()); + let num_args = u32::try_from(num_args).map_err(|core::num::TryFromIntError { .. }| { + Error::new( + Span::call_site(), + format!("too many arguments: {num_args} overflows u32"), + ) + })?; + let header = Ident::new("__header", Span::call_site()); + let tmp = Ident::new("__tmp", Span::call_site()); + let kind = Ident::new("__kind", Span::call_site()); + let value = Ident::new("__value", Span::call_site()); + let size = Ident::new("__size", Span::call_site()); + let op = Ident::new("__op", Span::call_site()); + let buf = Ident::new("__buf", Span::call_site()); Ok(quote! { - match ::aya_log_ebpf::macro_support::AYA_LOG_BUF.get_ptr_mut(0).and_then(|ptr| unsafe { ptr.as_mut() }) { - None => {}, - Some(::aya_log_ebpf::macro_support::LogBuf { buf: #buf }) => { - // Silence unused variable warning; we may need ctx in the future. - let _ = #ctx; - let _: Option<()> = (|| { - let #size = ::aya_log_ebpf::macro_support::write_record_header( - #buf, - #target, - #level, - module_path!(), - file!(), - line!(), - #num_args, - )?; - let mut #size = #size.get(); - #( - { - let #buf = #buf.get_mut(#size..)?; - let #len = ::aya_log_ebpf::macro_support::WriteToBuf::write(#values_iter, #buf)?; - #size += #len.get(); - } - )* - let #record = #buf.get(..#size)?; - Result::<_, i64>::ok(::aya_log_ebpf::macro_support::AYA_LOGS.output(#record, 0)) - })(); + // Silence unused variable warning; we may need ctx in the future. + let _ = #ctx; + let _: Option<()> = (|| { + use ::aya_log_ebpf::macro_support::{Header, Field, Argument, AYA_LOGS}; + + let #header = Header::new( + #target, + #level, + module_path!(), + file!(), + line!(), + #num_args, + )?; + + #( + let #tmp = #values; + let (#kind, #value) = #tmp.as_argument(); + let #idents = Field::new(#kind, #value)?; + )* + + let mut #size = 0; + let mut #op = |slice: &[u8]| { + #size += slice.len(); + Some(()) + }; + #header.with_bytes(&mut #op)?; + #( + #idents.with_bytes(&mut #op)?; + )* + + let mut #buf = AYA_LOGS.reserve_bytes(#size, 0)?; + + match (|| { + let mut #size = 0; + let mut #op = |slice: &[u8]| { + let #buf = #buf.get_mut(#size..)?; + let #buf = #buf.get_mut(..slice.len())?; + #buf.copy_from_slice(slice); + #size += slice.len(); + Some(()) + }; + #header.with_bytes(&mut #op)?; + #( + #idents.with_bytes(&mut #op)?; + )* + Some(()) + })() { + Some(()) => #buf.submit(0), + None => #buf.discard(0), } - } + + Some(()) + })(); }) } diff --git a/aya-log/src/lib.rs b/aya-log/src/lib.rs index e34c3ba6..92df6c90 100644 --- a/aya-log/src/lib.rs +++ b/aya-log/src/lib.rs @@ -72,16 +72,16 @@ use aya::{ maps::{Map, MapData, MapError, MapInfo, RingBuf}, programs::{ProgramError, loaded_programs}, }; -use aya_log_common::{Argument, DisplayHint, LOG_FIELDS, Level, LogValueLength, RecordField}; +use aya_log_common::{ArgumentKind, DisplayHint, Level, LogValueLength, RecordFieldKind}; use log::{Log, Record, error}; use thiserror::Error; #[derive(Copy, Clone)] #[repr(transparent)] -struct RecordFieldWrapper(RecordField); +struct RecordFieldWrapper(RecordFieldKind); #[derive(Copy, Clone)] #[repr(transparent)] -struct ArgumentWrapper(Argument); +struct ArgumentWrapper(ArgumentKind); #[derive(Copy, Clone)] #[repr(transparent)] struct DisplayHintWrapper(DisplayHint); @@ -457,15 +457,25 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { let mut line = None; let mut num_args = None; - for () in std::iter::repeat_n((), LOG_FIELDS) { + while target.is_none() + || level.is_none() + || module.is_none() + || file.is_none() + || line.is_none() + || num_args.is_none() + { let (RecordFieldWrapper(tag), value, rest) = try_read(buf)?; match tag { - RecordField::Target => { - target = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + RecordFieldKind::Target => { + let target = + target.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + if target.is_some() { + return Err(()); + } } - RecordField::Level => { - level = Some({ + RecordFieldKind::Level => { + let level = level.replace({ let level = unsafe { ptr::read_unaligned(value.as_ptr() as *const _) }; match level { Level::Error => log::Level::Error, @@ -474,27 +484,44 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { Level::Debug => log::Level::Debug, Level::Trace => log::Level::Trace, } - }) + }); + if level.is_some() { + return Err(()); + } } - RecordField::Module => { - module = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + RecordFieldKind::Module => { + let module = + module.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + if module.is_some() { + return Err(()); + } } - RecordField::File => { - file = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + RecordFieldKind::File => { + let file = + file.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); + if file.is_some() { + return Err(()); + } } - RecordField::Line => { - line = Some(u32::from_ne_bytes( + RecordFieldKind::Line => { + let line = line.replace(u32::from_ne_bytes( value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?, )); + if line.is_some() { + return Err(()); + } } - RecordField::NumArgs => { - num_args = Some(usize::from_ne_bytes( + RecordFieldKind::NumArgs => { + let num_args = num_args.replace(u32::from_ne_bytes( value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?, )); + if num_args.is_some() { + return Err(()); + } } } @@ -503,14 +530,17 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { let mut full_log_msg = String::new(); let mut last_hint: Option = None; - for () in std::iter::repeat_n((), num_args.ok_or(())?) { + let num_args = num_args.ok_or(()).and_then(|num_args| { + usize::try_from(num_args).map_err(|std::num::TryFromIntError { .. }| ()) + })?; + for () in std::iter::repeat_n((), num_args) { let (ArgumentWrapper(tag), value, rest) = try_read(buf)?; match tag { - Argument::DisplayHint => { + ArgumentKind::DisplayHint => { last_hint = Some(unsafe { ptr::read_unaligned(value.as_ptr() as *const _) }); } - Argument::I8 => { + ArgumentKind::I8 => { full_log_msg.push_str( &i8::from_ne_bytes( value @@ -520,7 +550,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::I16 => { + ArgumentKind::I16 => { full_log_msg.push_str( &i16::from_ne_bytes( value @@ -530,7 +560,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::I32 => { + ArgumentKind::I32 => { full_log_msg.push_str( &i32::from_ne_bytes( value @@ -540,7 +570,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::I64 => { + ArgumentKind::I64 => { full_log_msg.push_str( &i64::from_ne_bytes( value @@ -550,7 +580,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::Isize => { + ArgumentKind::Isize => { full_log_msg.push_str( &isize::from_ne_bytes( value @@ -560,7 +590,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::U8 => { + ArgumentKind::U8 => { full_log_msg.push_str( &u8::from_ne_bytes( value @@ -570,7 +600,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::U16 => { + ArgumentKind::U16 => { full_log_msg.push_str( &u16::from_ne_bytes( value @@ -580,7 +610,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::U32 => { + ArgumentKind::U32 => { full_log_msg.push_str( &u32::from_ne_bytes( value @@ -590,7 +620,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::U64 => { + ArgumentKind::U64 => { full_log_msg.push_str( &u64::from_ne_bytes( value @@ -600,7 +630,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::Usize => { + ArgumentKind::Usize => { full_log_msg.push_str( &usize::from_ne_bytes( value @@ -610,7 +640,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::F32 => { + ArgumentKind::F32 => { full_log_msg.push_str( &f32::from_ne_bytes( value @@ -620,7 +650,7 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::F64 => { + ArgumentKind::F64 => { full_log_msg.push_str( &f64::from_ne_bytes( value @@ -630,39 +660,39 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { .format(last_hint.take())?, ); } - Argument::Ipv4Addr => { + ArgumentKind::Ipv4Addr => { let value: [u8; 4] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; let value = Ipv4Addr::from(value); full_log_msg.push_str(&value.format(last_hint.take())?) } - Argument::Ipv6Addr => { + ArgumentKind::Ipv6Addr => { let value: [u8; 16] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; let value = Ipv6Addr::from(value); full_log_msg.push_str(&value.format(last_hint.take())?) } - Argument::ArrU8Len4 => { + ArgumentKind::ArrU8Len4 => { let value: [u8; 4] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; full_log_msg.push_str(&value.format(last_hint.take())?); } - Argument::ArrU8Len6 => { + ArgumentKind::ArrU8Len6 => { let value: [u8; 6] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; full_log_msg.push_str(&value.format(last_hint.take())?); } - Argument::ArrU8Len16 => { + ArgumentKind::ArrU8Len16 => { let value: [u8; 16] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; full_log_msg.push_str(&value.format(last_hint.take())?); } - Argument::ArrU16Len8 => { + ArgumentKind::ArrU16Len8 => { let data: [u8; 16] = value .try_into() .map_err(|std::array::TryFromSliceError { .. }| ())?; @@ -672,10 +702,10 @@ fn log_buf(mut buf: &[u8], logger: &T) -> Result<(), ()> { } full_log_msg.push_str(&value.format(last_hint.take())?); } - Argument::Bytes => { + ArgumentKind::Bytes => { full_log_msg.push_str(&value.format(last_hint.take())?); } - Argument::Str => match str::from_utf8(value) { + ArgumentKind::Str => match str::from_utf8(value) { Ok(v) => { full_log_msg.push_str(v); } @@ -723,14 +753,57 @@ fn try_read(mut buf: &[u8]) -> Result<(T, &[u8], &[u8]), ()> { #[cfg(test)] mod test { - use std::net::IpAddr; + use std::{net::IpAddr, num::NonZeroUsize}; - use aya_log_common::{WriteToBuf as _, write_record_header}; + use aya_log_common::{Argument, Field, Header}; use log::{Level, logger}; + trait WriteToBuf { + fn write(self, buf: &mut [u8]) -> Option; + } + + impl WriteToBuf for T { + fn write(self, buf: &mut [u8]) -> Option { + let (kind, value) = self.as_argument(); + let field = Field::new(kind, value)?; + let mut size = 0; + let mut op = |slice: &[u8]| { + let buf = buf.get_mut(size..)?; + let buf = buf.get_mut(..slice.len())?; + buf.copy_from_slice(slice); + size += slice.len(); + Some(()) + }; + field.with_bytes(&mut op)?; + NonZeroUsize::new(size) + } + } + use super::*; - fn new_log(args: usize) -> Option<(usize, Vec)> { + fn write_record_header( + buf: &mut [u8], + target: &str, + level: aya_log_common::Level, + module: &str, + file: &str, + line: u32, + num_args: u32, + ) -> Option { + let header = Header::new(target, level, module, file, line, num_args)?; + let mut size = 0; + let mut op = |slice: &[u8]| { + let buf = buf.get_mut(size..)?; + let buf = buf.get_mut(..slice.len())?; + buf.copy_from_slice(slice); + size += slice.len(); + Some(()) + }; + header.with_bytes(&mut op)?; + NonZeroUsize::new(size) + } + + fn new_log(args: u32) -> Option<(usize, Vec)> { let mut buf = vec![0; 8192]; let len = write_record_header( &mut buf, diff --git a/ebpf/aya-log-ebpf/src/lib.rs b/ebpf/aya-log-ebpf/src/lib.rs index 0a3f1421..b1f77fb7 100644 --- a/ebpf/aya-log-ebpf/src/lib.rs +++ b/ebpf/aya-log-ebpf/src/lib.rs @@ -7,27 +7,15 @@ pub use aya_log_ebpf_macros::{debug, error, info, log, trace, warn}; pub mod macro_support { #[cfg(target_arch = "bpf")] use aya_ebpf::macros::map; - use aya_ebpf::maps::{PerCpuArray, RingBuf}; + use aya_ebpf::maps::RingBuf; use aya_log_common::LogValueLength; pub use aya_log_common::{ - DefaultFormatter, DisplayHint, IpFormatter, Level, LowerHexFormatter, LowerMacFormatter, - UpperHexFormatter, UpperMacFormatter, WriteToBuf, write_record_header, + Argument, DefaultFormatter, DisplayHint, Field, Header, IpFormatter, Level, + LowerHexFormatter, LowerMacFormatter, UpperHexFormatter, UpperMacFormatter, }; const LOG_BUF_CAPACITY: LogValueLength = 8192; - #[repr(C)] - pub struct LogBuf { - pub buf: [u8; LOG_BUF_CAPACITY as usize], - } - - // This cfg_attr prevents compilation failures on macOS where the generated section name doesn't - // meet mach-o's requirements. We wouldn't ordinarily build this crate for macOS, but we do so - // because the integration-test crate depends on this crate transitively. See comment in - // test/integration-test/Cargo.toml. - #[cfg_attr(target_arch = "bpf", map)] - pub static AYA_LOG_BUF: PerCpuArray = PerCpuArray::with_max_entries(1, 0); - // This cfg_attr prevents compilation failures on macOS where the generated section name doesn't // meet mach-o's requirements. We wouldn't ordinarily build this crate for macOS, but we do so // because the integration-test crate depends on this crate transitively. See comment in diff --git a/xtask/public-api/aya-log-common.txt b/xtask/public-api/aya-log-common.txt index c93ec712..92b7f314 100644 --- a/xtask/public-api/aya-log-common.txt +++ b/xtask/public-api/aya-log-common.txt @@ -1,57 +1,57 @@ pub mod aya_log_common -#[repr(u8)] pub enum aya_log_common::Argument -pub aya_log_common::Argument::ArrU16Len8 -pub aya_log_common::Argument::ArrU8Len16 -pub aya_log_common::Argument::ArrU8Len4 -pub aya_log_common::Argument::ArrU8Len6 -pub aya_log_common::Argument::Bytes -pub aya_log_common::Argument::DisplayHint -pub aya_log_common::Argument::F32 -pub aya_log_common::Argument::F64 -pub aya_log_common::Argument::I16 -pub aya_log_common::Argument::I32 -pub aya_log_common::Argument::I64 -pub aya_log_common::Argument::I8 -pub aya_log_common::Argument::Ipv4Addr -pub aya_log_common::Argument::Ipv6Addr -pub aya_log_common::Argument::Isize -pub aya_log_common::Argument::Str -pub aya_log_common::Argument::U16 -pub aya_log_common::Argument::U32 -pub aya_log_common::Argument::U64 -pub aya_log_common::Argument::U8 -pub aya_log_common::Argument::Usize -impl core::clone::Clone for aya_log_common::Argument -pub fn aya_log_common::Argument::clone(&self) -> aya_log_common::Argument -impl core::convert::From for u8 -pub fn u8::from(enum_value: aya_log_common::Argument) -> Self -impl core::fmt::Debug for aya_log_common::Argument -pub fn aya_log_common::Argument::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Copy for aya_log_common::Argument -impl core::marker::Freeze for aya_log_common::Argument -impl core::marker::Send for aya_log_common::Argument -impl core::marker::Sync for aya_log_common::Argument -impl core::marker::Unpin for aya_log_common::Argument -impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::Argument -impl core::panic::unwind_safe::UnwindSafe for aya_log_common::Argument -impl core::convert::Into for aya_log_common::Argument where U: core::convert::From -pub fn aya_log_common::Argument::into(self) -> U -impl core::convert::TryFrom for aya_log_common::Argument where U: core::convert::Into -pub type aya_log_common::Argument::Error = core::convert::Infallible -pub fn aya_log_common::Argument::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya_log_common::Argument where U: core::convert::TryFrom -pub type aya_log_common::Argument::Error = >::Error -pub fn aya_log_common::Argument::try_into(self) -> core::result::Result>::Error> -impl core::any::Any for aya_log_common::Argument where T: 'static + ?core::marker::Sized -pub fn aya_log_common::Argument::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya_log_common::Argument where T: ?core::marker::Sized -pub fn aya_log_common::Argument::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya_log_common::Argument where T: ?core::marker::Sized -pub fn aya_log_common::Argument::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya_log_common::Argument where T: core::clone::Clone -pub unsafe fn aya_log_common::Argument::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya_log_common::Argument -pub fn aya_log_common::Argument::from(t: T) -> T +#[repr(u8)] pub enum aya_log_common::ArgumentKind +pub aya_log_common::ArgumentKind::ArrU16Len8 +pub aya_log_common::ArgumentKind::ArrU8Len16 +pub aya_log_common::ArgumentKind::ArrU8Len4 +pub aya_log_common::ArgumentKind::ArrU8Len6 +pub aya_log_common::ArgumentKind::Bytes +pub aya_log_common::ArgumentKind::DisplayHint +pub aya_log_common::ArgumentKind::F32 +pub aya_log_common::ArgumentKind::F64 +pub aya_log_common::ArgumentKind::I16 +pub aya_log_common::ArgumentKind::I32 +pub aya_log_common::ArgumentKind::I64 +pub aya_log_common::ArgumentKind::I8 +pub aya_log_common::ArgumentKind::Ipv4Addr +pub aya_log_common::ArgumentKind::Ipv6Addr +pub aya_log_common::ArgumentKind::Isize +pub aya_log_common::ArgumentKind::Str +pub aya_log_common::ArgumentKind::U16 +pub aya_log_common::ArgumentKind::U32 +pub aya_log_common::ArgumentKind::U64 +pub aya_log_common::ArgumentKind::U8 +pub aya_log_common::ArgumentKind::Usize +impl core::clone::Clone for aya_log_common::ArgumentKind +pub fn aya_log_common::ArgumentKind::clone(&self) -> aya_log_common::ArgumentKind +impl core::convert::From for u8 +pub fn u8::from(enum_value: aya_log_common::ArgumentKind) -> Self +impl core::fmt::Debug for aya_log_common::ArgumentKind +pub fn aya_log_common::ArgumentKind::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya_log_common::ArgumentKind +impl core::marker::Freeze for aya_log_common::ArgumentKind +impl core::marker::Send for aya_log_common::ArgumentKind +impl core::marker::Sync for aya_log_common::ArgumentKind +impl core::marker::Unpin for aya_log_common::ArgumentKind +impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::ArgumentKind +impl core::panic::unwind_safe::UnwindSafe for aya_log_common::ArgumentKind +impl core::convert::Into for aya_log_common::ArgumentKind where U: core::convert::From +pub fn aya_log_common::ArgumentKind::into(self) -> U +impl core::convert::TryFrom for aya_log_common::ArgumentKind where U: core::convert::Into +pub type aya_log_common::ArgumentKind::Error = core::convert::Infallible +pub fn aya_log_common::ArgumentKind::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya_log_common::ArgumentKind where U: core::convert::TryFrom +pub type aya_log_common::ArgumentKind::Error = >::Error +pub fn aya_log_common::ArgumentKind::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya_log_common::ArgumentKind where T: 'static + ?core::marker::Sized +pub fn aya_log_common::ArgumentKind::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya_log_common::ArgumentKind where T: ?core::marker::Sized +pub fn aya_log_common::ArgumentKind::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya_log_common::ArgumentKind where T: ?core::marker::Sized +pub fn aya_log_common::ArgumentKind::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya_log_common::ArgumentKind where T: core::clone::Clone +pub unsafe fn aya_log_common::ArgumentKind::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya_log_common::ArgumentKind +pub fn aya_log_common::ArgumentKind::from(t: T) -> T #[repr(u8)] pub enum aya_log_common::DisplayHint pub aya_log_common::DisplayHint::Default = 1 pub aya_log_common::DisplayHint::Ip @@ -59,8 +59,8 @@ pub aya_log_common::DisplayHint::LowerHex pub aya_log_common::DisplayHint::LowerMac pub aya_log_common::DisplayHint::UpperHex pub aya_log_common::DisplayHint::UpperMac -impl aya_log_common::WriteToBuf for aya_log_common::DisplayHint -pub fn aya_log_common::DisplayHint::write(self, buf: &mut [u8]) -> core::option::Option +impl aya_log_common::Argument for aya_log_common::DisplayHint +pub fn aya_log_common::DisplayHint::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) impl core::clone::Clone for aya_log_common::DisplayHint pub fn aya_log_common::DisplayHint::clone(&self) -> aya_log_common::DisplayHint impl core::cmp::Eq for aya_log_common::DisplayHint @@ -139,45 +139,90 @@ impl core::clone::CloneToUninit for aya_log_common::Level where T: core::clon pub unsafe fn aya_log_common::Level::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya_log_common::Level pub fn aya_log_common::Level::from(t: T) -> T -#[repr(u8)] pub enum aya_log_common::RecordField -pub aya_log_common::RecordField::File -pub aya_log_common::RecordField::Level -pub aya_log_common::RecordField::Line -pub aya_log_common::RecordField::Module -pub aya_log_common::RecordField::NumArgs -pub aya_log_common::RecordField::Target = 1 -impl core::clone::Clone for aya_log_common::RecordField -pub fn aya_log_common::RecordField::clone(&self) -> aya_log_common::RecordField -impl core::convert::From for u8 -pub fn u8::from(enum_value: aya_log_common::RecordField) -> Self -impl core::fmt::Debug for aya_log_common::RecordField -pub fn aya_log_common::RecordField::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Copy for aya_log_common::RecordField -impl core::marker::Freeze for aya_log_common::RecordField -impl core::marker::Send for aya_log_common::RecordField -impl core::marker::Sync for aya_log_common::RecordField -impl core::marker::Unpin for aya_log_common::RecordField -impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::RecordField -impl core::panic::unwind_safe::UnwindSafe for aya_log_common::RecordField -impl core::convert::Into for aya_log_common::RecordField where U: core::convert::From -pub fn aya_log_common::RecordField::into(self) -> U -impl core::convert::TryFrom for aya_log_common::RecordField where U: core::convert::Into -pub type aya_log_common::RecordField::Error = core::convert::Infallible -pub fn aya_log_common::RecordField::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya_log_common::RecordField where U: core::convert::TryFrom -pub type aya_log_common::RecordField::Error = >::Error -pub fn aya_log_common::RecordField::try_into(self) -> core::result::Result>::Error> -impl core::any::Any for aya_log_common::RecordField where T: 'static + ?core::marker::Sized -pub fn aya_log_common::RecordField::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya_log_common::RecordField where T: ?core::marker::Sized -pub fn aya_log_common::RecordField::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya_log_common::RecordField where T: ?core::marker::Sized -pub fn aya_log_common::RecordField::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya_log_common::RecordField where T: core::clone::Clone -pub unsafe fn aya_log_common::RecordField::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya_log_common::RecordField -pub fn aya_log_common::RecordField::from(t: T) -> T -pub const aya_log_common::LOG_FIELDS: usize +#[repr(u8)] pub enum aya_log_common::RecordFieldKind +pub aya_log_common::RecordFieldKind::File +pub aya_log_common::RecordFieldKind::Level +pub aya_log_common::RecordFieldKind::Line +pub aya_log_common::RecordFieldKind::Module +pub aya_log_common::RecordFieldKind::NumArgs +pub aya_log_common::RecordFieldKind::Target +impl core::clone::Clone for aya_log_common::RecordFieldKind +pub fn aya_log_common::RecordFieldKind::clone(&self) -> aya_log_common::RecordFieldKind +impl core::convert::From for u8 +pub fn u8::from(enum_value: aya_log_common::RecordFieldKind) -> Self +impl core::fmt::Debug for aya_log_common::RecordFieldKind +pub fn aya_log_common::RecordFieldKind::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya_log_common::RecordFieldKind +impl core::marker::Freeze for aya_log_common::RecordFieldKind +impl core::marker::Send for aya_log_common::RecordFieldKind +impl core::marker::Sync for aya_log_common::RecordFieldKind +impl core::marker::Unpin for aya_log_common::RecordFieldKind +impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::RecordFieldKind +impl core::panic::unwind_safe::UnwindSafe for aya_log_common::RecordFieldKind +impl core::convert::Into for aya_log_common::RecordFieldKind where U: core::convert::From +pub fn aya_log_common::RecordFieldKind::into(self) -> U +impl core::convert::TryFrom for aya_log_common::RecordFieldKind where U: core::convert::Into +pub type aya_log_common::RecordFieldKind::Error = core::convert::Infallible +pub fn aya_log_common::RecordFieldKind::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya_log_common::RecordFieldKind where U: core::convert::TryFrom +pub type aya_log_common::RecordFieldKind::Error = >::Error +pub fn aya_log_common::RecordFieldKind::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya_log_common::RecordFieldKind where T: 'static + ?core::marker::Sized +pub fn aya_log_common::RecordFieldKind::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya_log_common::RecordFieldKind where T: ?core::marker::Sized +pub fn aya_log_common::RecordFieldKind::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya_log_common::RecordFieldKind where T: ?core::marker::Sized +pub fn aya_log_common::RecordFieldKind::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya_log_common::RecordFieldKind where T: core::clone::Clone +pub unsafe fn aya_log_common::RecordFieldKind::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya_log_common::RecordFieldKind +pub fn aya_log_common::RecordFieldKind::from(t: T) -> T +pub trait aya_log_common::Argument +pub fn aya_log_common::Argument::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for &[u8] +pub fn &[u8]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for &str +pub fn &str::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for [u16; 8] +pub fn [u16; 8]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for [u8; 16] +pub fn [u8; 16]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for [u8; 4] +pub fn [u8; 4]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for [u8; 6] +pub fn [u8; 6]::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for aya_log_common::DisplayHint +pub fn aya_log_common::DisplayHint::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for core::net::ip_addr::IpAddr +pub fn core::net::ip_addr::IpAddr::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for core::net::ip_addr::Ipv4Addr +pub fn core::net::ip_addr::Ipv4Addr::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for core::net::ip_addr::Ipv6Addr +pub fn core::net::ip_addr::Ipv6Addr::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for f32 +pub fn f32::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for f64 +pub fn f64::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for i16 +pub fn i16::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for i32 +pub fn i32::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for i64 +pub fn i64::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for i8 +pub fn i8::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for isize +pub fn isize::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for u16 +pub fn u16::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for u32 +pub fn u32::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for u64 +pub fn u64::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for u8 +pub fn u8::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) +impl aya_log_common::Argument for usize +pub fn usize::as_argument(&self) -> (aya_log_common::ArgumentKind, impl core::convert::AsRef<[u8]>) pub trait aya_log_common::DefaultFormatter impl aya_log_common::DefaultFormatter for &str impl aya_log_common::DefaultFormatter for bool @@ -234,50 +279,4 @@ impl aya_log_common::UpperHexFormatter for u8 impl aya_log_common::UpperHexFormatter for usize pub trait aya_log_common::UpperMacFormatter impl aya_log_common::UpperMacFormatter for [u8; 6] -pub trait aya_log_common::WriteToBuf -pub fn aya_log_common::WriteToBuf::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for &[u8] -pub fn &[u8]::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for &str -pub fn &str::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for [u16; 8] -pub fn [u16; 8]::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for [u8; 16] -pub fn [u8; 16]::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for [u8; 4] -pub fn [u8; 4]::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for [u8; 6] -pub fn [u8; 6]::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for aya_log_common::DisplayHint -pub fn aya_log_common::DisplayHint::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for core::net::ip_addr::IpAddr -pub fn core::net::ip_addr::IpAddr::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for core::net::ip_addr::Ipv4Addr -pub fn core::net::ip_addr::Ipv4Addr::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for core::net::ip_addr::Ipv6Addr -pub fn core::net::ip_addr::Ipv6Addr::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for f32 -pub fn f32::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for f64 -pub fn f64::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for i16 -pub fn i16::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for i32 -pub fn i32::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for i64 -pub fn i64::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for i8 -pub fn i8::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for isize -pub fn isize::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for u16 -pub fn u16::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for u32 -pub fn u32::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for u64 -pub fn u64::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for u8 -pub fn u8::write(self, buf: &mut [u8]) -> core::option::Option -impl aya_log_common::WriteToBuf for usize -pub fn usize::write(self, buf: &mut [u8]) -> core::option::Option pub type aya_log_common::LogValueLength = u16