aya-log-ebpf: zero copy!

reviewable/pr1294/r5
Tamir Duberstein 3 weeks ago
parent 8354cbcece
commit 25c8d956c4
No known key found for this signature in database

@ -2,13 +2,11 @@
use core::{ use core::{
net::{IpAddr, Ipv4Addr, Ipv6Addr}, net::{IpAddr, Ipv4Addr, Ipv6Addr},
num::{NonZeroUsize, TryFromIntError}, num::TryFromIntError,
}; };
use num_enum::IntoPrimitive; use num_enum::IntoPrimitive;
pub const LOG_FIELDS: usize = 6;
pub type LogValueLength = u16; pub type LogValueLength = u16;
#[repr(u8)] #[repr(u8)]
@ -93,8 +91,8 @@ impl UpperMacFormatter for [u8; 6] {}
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone, Debug, IntoPrimitive)] #[derive(Copy, Clone, Debug, IntoPrimitive)]
pub enum RecordField { pub enum RecordFieldKind {
Target = 1, Target,
Level, Level,
Module, Module,
File, File,
@ -106,7 +104,7 @@ pub enum RecordField {
/// programs to userspace. /// programs to userspace.
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone, Debug, IntoPrimitive)] #[derive(Copy, Clone, Debug, IntoPrimitive)]
pub enum Argument { pub enum ArgumentKind {
DisplayHint, DisplayHint,
I8, I8,
@ -158,172 +156,207 @@ pub enum DisplayHint {
UpperMac, UpperMac,
} }
// Must be inlined, else the BPF backend emits: pub trait Argument {
// fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>);
// llvm: <unknown>: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<NonZeroUsize> {
// 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<NonZeroUsize>;
} }
macro_rules! impl_write_to_buf { macro_rules! impl_argument {
($type:ident, $arg_type:expr) => { ($self:ident, $arg_type:expr) => {
impl WriteToBuf for $type { impl Argument for $self {
// This need not be inlined because the return value is Option<N> where N is fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// mem::size_of<$type>, which is a compile-time constant. ($arg_type, self.to_ne_bytes())
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
write($arg_type.into(), &self.to_ne_bytes(), buf)
} }
} }
}; };
} }
impl_write_to_buf!(i8, Argument::I8); impl_argument!(i8, ArgumentKind::I8);
impl_write_to_buf!(i16, Argument::I16); impl_argument!(i16, ArgumentKind::I16);
impl_write_to_buf!(i32, Argument::I32); impl_argument!(i32, ArgumentKind::I32);
impl_write_to_buf!(i64, Argument::I64); impl_argument!(i64, ArgumentKind::I64);
impl_write_to_buf!(isize, Argument::Isize); 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_argument!(f32, ArgumentKind::F32);
impl_write_to_buf!(u16, Argument::U16); impl_argument!(f64, ArgumentKind::F64);
impl_write_to_buf!(u32, Argument::U32);
impl_write_to_buf!(u64, Argument::U64);
impl_write_to_buf!(usize, Argument::Usize);
impl_write_to_buf!(f32, Argument::F32); enum Either<L, R> {
impl_write_to_buf!(f64, Argument::F64); Left(L),
Right(R),
}
impl WriteToBuf for IpAddr { impl<L, R> AsRef<[u8]> for Either<L, R>
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> { where
L: AsRef<[u8]>,
R: AsRef<[u8]>,
{
fn as_ref(&self) -> &[u8] {
match self { match self {
IpAddr::V4(ipv4_addr) => write(Argument::Ipv4Addr.into(), &ipv4_addr.octets(), buf), Either::Left(l) => l.as_ref(),
IpAddr::V6(ipv6_addr) => write(Argument::Ipv6Addr.into(), &ipv6_addr.octets(), buf), Either::Right(r) => r.as_ref(),
} }
} }
} }
impl WriteToBuf for Ipv4Addr { impl Argument for IpAddr {
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> { fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
write(Argument::Ipv4Addr.into(), &self.octets(), buf) 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] { impl Argument for Ipv4Addr {
// This need not be inlined because the return value is Option<N> where N is 16, which is a fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// compile-time constant. (ArgumentKind::Ipv4Addr, self.octets())
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
write(Argument::ArrU8Len4.into(), &self, buf)
} }
} }
impl WriteToBuf for Ipv6Addr { impl Argument for [u8; 4] {
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> { fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
write(Argument::Ipv6Addr.into(), &self.octets(), buf) (ArgumentKind::ArrU8Len4, self)
} }
} }
impl WriteToBuf for [u8; 16] { impl Argument for Ipv6Addr {
// This need not be inlined because the return value is Option<N> where N is 16, which is a fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// compile-time constant. (ArgumentKind::Ipv6Addr, self.octets())
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
write(Argument::ArrU8Len16.into(), &self, buf)
} }
} }
impl WriteToBuf for [u16; 8] { impl Argument for [u8; 16] {
// This need not be inlined because the return value is Option<N> where N is 16, which is a fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// compile-time constant. (ArgumentKind::ArrU8Len16, self)
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
let bytes = unsafe { core::mem::transmute::<[u16; 8], [u8; 16]>(self) };
write(Argument::ArrU16Len8.into(), &bytes, buf)
} }
} }
impl WriteToBuf for [u8; 6] { impl Argument for [u16; 8] {
// This need not be inlined because the return value is Option<N> where N is 6, which is a fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// compile-time constant. let bytes = unsafe { core::mem::transmute::<&[u16; 8], &[u8; 16]>(self) };
#[inline(never)] (ArgumentKind::ArrU16Len8, bytes)
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
write(Argument::ArrU8Len6.into(), &self, buf)
} }
} }
impl WriteToBuf for &[u8] { impl Argument for [u8; 6] {
// Must be inlined, else the BPF backend emits: fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// (ArgumentKind::ArrU8Len6, self)
// llvm: <unknown>: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<NonZeroUsize> {
write(Argument::Bytes.into(), self, buf)
} }
} }
impl WriteToBuf for &str { impl Argument for &[u8] {
// Must be inlined, else the BPF backend emits: fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// (ArgumentKind::Bytes, self)
// llvm: <unknown>: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<NonZeroUsize> {
write(Argument::Str.into(), self.as_bytes(), buf)
} }
} }
impl WriteToBuf for DisplayHint { impl Argument for &str {
// This need not be inlined because the return value is Option<N> where N is 1, which is a fn as_argument(&self) -> (ArgumentKind, impl AsRef<[u8]>) {
// compile-time constant. (ArgumentKind::Str, self.as_bytes())
#[inline(never)] }
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> { }
let v: u8 = self.into();
write(Argument::DisplayHint.into(), &v.to_ne_bytes(), buf) 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<T>([u8; 1], [u8; 2], T);
impl<T: AsRef<[u8]>> Field<T> {
pub fn new(kind: impl Into<u8>, value: T) -> Option<Self> {
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)] #[doc(hidden)]
#[inline(always)] // This function takes too many arguments to not be inlined. pub struct Header<'a> {
pub fn write_record_header( target: Field<&'a [u8]>,
buf: &mut [u8], level: Field<[u8; 1]>,
target: &str, module: Field<&'a [u8]>,
level: Level, file: Field<&'a [u8]>,
module: &str, line: Field<[u8; 4]>,
file: &str, num_args: Field<[u8; 4]>,
line: u32, }
num_args: usize,
) -> Option<NonZeroUsize> { impl<'a> Header<'a> {
let level: u8 = level.into(); pub fn new(
let mut size = 0; target: &'a str,
for (tag, value) in [ level: Level,
(RecordField::Target, target.as_bytes()), module: &'a str,
(RecordField::Level, &level.to_ne_bytes()), file: &'a str,
(RecordField::Module, module.as_bytes()), line: u32,
(RecordField::File, file.as_bytes()), num_args: u32,
(RecordField::Line, &line.to_ne_bytes()), ) -> Option<Self> {
(RecordField::NumArgs, &num_args.to_ne_bytes()), let target = target.as_bytes();
] { let level: u8 = level.into();
let buf = buf.get_mut(size..)?; let level = level.to_ne_bytes();
let len = write(tag.into(), value, buf)?; let module = module.as_bytes();
size += len.get(); 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)
} }

@ -1,5 +1,5 @@
use aya_log_common::DisplayHint; 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 proc_macro2::{Ident, Span, TokenStream};
use quote::quote; use quote::quote;
use syn::{ use syn::{
@ -105,12 +105,12 @@ pub(crate) fn log(args: LogArgs, level: Option<TokenStream>) -> Result<TokenStre
for fragment in fragments { for fragment in fragments {
match fragment { match fragment {
Fragment::Literal(s) => values.push(quote!(#s)), Fragment::Literal(s) => values.push(quote!(#s)),
Fragment::Parameter(p) => { Fragment::Parameter(Parameter { hint }) => {
let arg = match formatting_args { let arg = match &formatting_args {
Some(ref args) => args[arg_i].clone(), Some(args) => &args[arg_i],
None => return Err(Error::new(format_string.span(), "no arguments provided")), None => return Err(Error::new(format_string.span(), "no arguments provided")),
}; };
let (hint, formatter) = match p.hint { let (hint, formatter) = match hint {
DisplayHint::Default => { DisplayHint::Default => {
(quote!(DisplayHint::Default), quote!(DefaultFormatter)) (quote!(DisplayHint::Default), quote!(DefaultFormatter))
} }
@ -144,41 +144,78 @@ pub(crate) fn log(args: LogArgs, level: Option<TokenStream>) -> Result<TokenStre
} }
} }
let idents: Vec<_> = (0..values.len())
.map(|arg_i| quote::format_ident!("__arg{arg_i}"))
.collect();
let num_args = values.len(); let num_args = values.len();
let values_iter = values.iter(); let num_args = u32::try_from(num_args).map_err(|core::num::TryFromIntError { .. }| {
let buf = Ident::new("buf", Span::mixed_site()); Error::new(
let size = Ident::new("size", Span::mixed_site()); Span::call_site(),
let len = Ident::new("len", Span::mixed_site()); format!("too many arguments: {num_args} overflows u32"),
let record = Ident::new("record", Span::mixed_site()); )
})?;
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! { Ok(quote! {
match ::aya_log_ebpf::macro_support::AYA_LOG_BUF.get_ptr_mut(0).and_then(|ptr| unsafe { ptr.as_mut() }) { // Silence unused variable warning; we may need ctx in the future.
None => {}, let _ = #ctx;
Some(::aya_log_ebpf::macro_support::LogBuf { buf: #buf }) => { let _: Option<()> = (|| {
// Silence unused variable warning; we may need ctx in the future. use ::aya_log_ebpf::macro_support::{Header, Field, Argument, AYA_LOGS};
let _ = #ctx;
let _: Option<()> = (|| { let #header = Header::new(
let #size = ::aya_log_ebpf::macro_support::write_record_header( #target,
#buf, #level,
#target, module_path!(),
#level, file!(),
module_path!(), line!(),
file!(), #num_args,
line!(), )?;
#num_args,
)?; #(
let mut #size = #size.get(); let #tmp = #values;
#( let (#kind, #value) = #tmp.as_argument();
{ let #idents = Field::new(#kind, #value)?;
let #buf = #buf.get_mut(#size..)?; )*
let #len = ::aya_log_ebpf::macro_support::WriteToBuf::write(#values_iter, #buf)?;
#size += #len.get(); let mut #size = 0;
} let mut #op = |slice: &[u8]| {
)* #size += slice.len();
let #record = #buf.get(..#size)?; Some(())
Result::<_, i64>::ok(::aya_log_ebpf::macro_support::AYA_LOGS.output(#record, 0)) };
})(); #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(())
})();
}) })
} }

@ -72,16 +72,16 @@ use aya::{
maps::{Map, MapData, MapError, MapInfo, RingBuf}, maps::{Map, MapData, MapError, MapInfo, RingBuf},
programs::{ProgramError, loaded_programs}, 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 log::{Log, Record, error};
use thiserror::Error; use thiserror::Error;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct RecordFieldWrapper(RecordField); struct RecordFieldWrapper(RecordFieldKind);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct ArgumentWrapper(Argument); struct ArgumentWrapper(ArgumentKind);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct DisplayHintWrapper(DisplayHint); struct DisplayHintWrapper(DisplayHint);
@ -457,15 +457,25 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
let mut line = None; let mut line = None;
let mut num_args = 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)?; let (RecordFieldWrapper(tag), value, rest) = try_read(buf)?;
match tag { match tag {
RecordField::Target => { RecordFieldKind::Target => {
target = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); let target =
target.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?);
if target.is_some() {
return Err(());
}
} }
RecordField::Level => { RecordFieldKind::Level => {
level = Some({ let level = level.replace({
let level = unsafe { ptr::read_unaligned(value.as_ptr() as *const _) }; let level = unsafe { ptr::read_unaligned(value.as_ptr() as *const _) };
match level { match level {
Level::Error => log::Level::Error, Level::Error => log::Level::Error,
@ -474,27 +484,44 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
Level::Debug => log::Level::Debug, Level::Debug => log::Level::Debug,
Level::Trace => log::Level::Trace, Level::Trace => log::Level::Trace,
} }
}) });
if level.is_some() {
return Err(());
}
} }
RecordField::Module => { RecordFieldKind::Module => {
module = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); let module =
module.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?);
if module.is_some() {
return Err(());
}
} }
RecordField::File => { RecordFieldKind::File => {
file = Some(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?); let file =
file.replace(str::from_utf8(value).map_err(|std::str::Utf8Error { .. }| ())?);
if file.is_some() {
return Err(());
}
} }
RecordField::Line => { RecordFieldKind::Line => {
line = Some(u32::from_ne_bytes( let line = line.replace(u32::from_ne_bytes(
value value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?, .map_err(|std::array::TryFromSliceError { .. }| ())?,
)); ));
if line.is_some() {
return Err(());
}
} }
RecordField::NumArgs => { RecordFieldKind::NumArgs => {
num_args = Some(usize::from_ne_bytes( let num_args = num_args.replace(u32::from_ne_bytes(
value value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?, .map_err(|std::array::TryFromSliceError { .. }| ())?,
)); ));
if num_args.is_some() {
return Err(());
}
} }
} }
@ -503,14 +530,17 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
let mut full_log_msg = String::new(); let mut full_log_msg = String::new();
let mut last_hint: Option<DisplayHintWrapper> = None; let mut last_hint: Option<DisplayHintWrapper> = 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)?; let (ArgumentWrapper(tag), value, rest) = try_read(buf)?;
match tag { match tag {
Argument::DisplayHint => { ArgumentKind::DisplayHint => {
last_hint = Some(unsafe { ptr::read_unaligned(value.as_ptr() as *const _) }); last_hint = Some(unsafe { ptr::read_unaligned(value.as_ptr() as *const _) });
} }
Argument::I8 => { ArgumentKind::I8 => {
full_log_msg.push_str( full_log_msg.push_str(
&i8::from_ne_bytes( &i8::from_ne_bytes(
value value
@ -520,7 +550,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::I16 => { ArgumentKind::I16 => {
full_log_msg.push_str( full_log_msg.push_str(
&i16::from_ne_bytes( &i16::from_ne_bytes(
value value
@ -530,7 +560,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::I32 => { ArgumentKind::I32 => {
full_log_msg.push_str( full_log_msg.push_str(
&i32::from_ne_bytes( &i32::from_ne_bytes(
value value
@ -540,7 +570,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::I64 => { ArgumentKind::I64 => {
full_log_msg.push_str( full_log_msg.push_str(
&i64::from_ne_bytes( &i64::from_ne_bytes(
value value
@ -550,7 +580,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::Isize => { ArgumentKind::Isize => {
full_log_msg.push_str( full_log_msg.push_str(
&isize::from_ne_bytes( &isize::from_ne_bytes(
value value
@ -560,7 +590,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::U8 => { ArgumentKind::U8 => {
full_log_msg.push_str( full_log_msg.push_str(
&u8::from_ne_bytes( &u8::from_ne_bytes(
value value
@ -570,7 +600,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::U16 => { ArgumentKind::U16 => {
full_log_msg.push_str( full_log_msg.push_str(
&u16::from_ne_bytes( &u16::from_ne_bytes(
value value
@ -580,7 +610,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::U32 => { ArgumentKind::U32 => {
full_log_msg.push_str( full_log_msg.push_str(
&u32::from_ne_bytes( &u32::from_ne_bytes(
value value
@ -590,7 +620,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::U64 => { ArgumentKind::U64 => {
full_log_msg.push_str( full_log_msg.push_str(
&u64::from_ne_bytes( &u64::from_ne_bytes(
value value
@ -600,7 +630,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::Usize => { ArgumentKind::Usize => {
full_log_msg.push_str( full_log_msg.push_str(
&usize::from_ne_bytes( &usize::from_ne_bytes(
value value
@ -610,7 +640,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::F32 => { ArgumentKind::F32 => {
full_log_msg.push_str( full_log_msg.push_str(
&f32::from_ne_bytes( &f32::from_ne_bytes(
value value
@ -620,7 +650,7 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::F64 => { ArgumentKind::F64 => {
full_log_msg.push_str( full_log_msg.push_str(
&f64::from_ne_bytes( &f64::from_ne_bytes(
value value
@ -630,39 +660,39 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
.format(last_hint.take())?, .format(last_hint.take())?,
); );
} }
Argument::Ipv4Addr => { ArgumentKind::Ipv4Addr => {
let value: [u8; 4] = value let value: [u8; 4] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
let value = Ipv4Addr::from(value); let value = Ipv4Addr::from(value);
full_log_msg.push_str(&value.format(last_hint.take())?) full_log_msg.push_str(&value.format(last_hint.take())?)
} }
Argument::Ipv6Addr => { ArgumentKind::Ipv6Addr => {
let value: [u8; 16] = value let value: [u8; 16] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
let value = Ipv6Addr::from(value); let value = Ipv6Addr::from(value);
full_log_msg.push_str(&value.format(last_hint.take())?) full_log_msg.push_str(&value.format(last_hint.take())?)
} }
Argument::ArrU8Len4 => { ArgumentKind::ArrU8Len4 => {
let value: [u8; 4] = value let value: [u8; 4] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
full_log_msg.push_str(&value.format(last_hint.take())?); full_log_msg.push_str(&value.format(last_hint.take())?);
} }
Argument::ArrU8Len6 => { ArgumentKind::ArrU8Len6 => {
let value: [u8; 6] = value let value: [u8; 6] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
full_log_msg.push_str(&value.format(last_hint.take())?); full_log_msg.push_str(&value.format(last_hint.take())?);
} }
Argument::ArrU8Len16 => { ArgumentKind::ArrU8Len16 => {
let value: [u8; 16] = value let value: [u8; 16] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
full_log_msg.push_str(&value.format(last_hint.take())?); full_log_msg.push_str(&value.format(last_hint.take())?);
} }
Argument::ArrU16Len8 => { ArgumentKind::ArrU16Len8 => {
let data: [u8; 16] = value let data: [u8; 16] = value
.try_into() .try_into()
.map_err(|std::array::TryFromSliceError { .. }| ())?; .map_err(|std::array::TryFromSliceError { .. }| ())?;
@ -672,10 +702,10 @@ fn log_buf<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
} }
full_log_msg.push_str(&value.format(last_hint.take())?); full_log_msg.push_str(&value.format(last_hint.take())?);
} }
Argument::Bytes => { ArgumentKind::Bytes => {
full_log_msg.push_str(&value.format(last_hint.take())?); 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) => { Ok(v) => {
full_log_msg.push_str(v); full_log_msg.push_str(v);
} }
@ -723,14 +753,57 @@ fn try_read<T: Pod>(mut buf: &[u8]) -> Result<(T, &[u8], &[u8]), ()> {
#[cfg(test)] #[cfg(test)]
mod 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}; use log::{Level, logger};
trait WriteToBuf {
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize>;
}
impl<T: Argument> WriteToBuf for T {
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
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::*; use super::*;
fn new_log(args: usize) -> Option<(usize, Vec<u8>)> { fn write_record_header(
buf: &mut [u8],
target: &str,
level: aya_log_common::Level,
module: &str,
file: &str,
line: u32,
num_args: u32,
) -> Option<NonZeroUsize> {
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<u8>)> {
let mut buf = vec![0; 8192]; let mut buf = vec![0; 8192];
let len = write_record_header( let len = write_record_header(
&mut buf, &mut buf,

@ -7,27 +7,15 @@ pub use aya_log_ebpf_macros::{debug, error, info, log, trace, warn};
pub mod macro_support { pub mod macro_support {
#[cfg(target_arch = "bpf")] #[cfg(target_arch = "bpf")]
use aya_ebpf::macros::map; use aya_ebpf::macros::map;
use aya_ebpf::maps::{PerCpuArray, RingBuf}; use aya_ebpf::maps::RingBuf;
use aya_log_common::LogValueLength; use aya_log_common::LogValueLength;
pub use aya_log_common::{ pub use aya_log_common::{
DefaultFormatter, DisplayHint, IpFormatter, Level, LowerHexFormatter, LowerMacFormatter, Argument, DefaultFormatter, DisplayHint, Field, Header, IpFormatter, Level,
UpperHexFormatter, UpperMacFormatter, WriteToBuf, write_record_header, LowerHexFormatter, LowerMacFormatter, UpperHexFormatter, UpperMacFormatter,
}; };
const LOG_BUF_CAPACITY: LogValueLength = 8192; 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<LogBuf> = PerCpuArray::with_max_entries(1, 0);
// This cfg_attr prevents compilation failures on macOS where the generated section name doesn't // 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 // 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 // because the integration-test crate depends on this crate transitively. See comment in

@ -1,57 +1,57 @@
pub mod aya_log_common pub mod aya_log_common
#[repr(u8)] pub enum aya_log_common::Argument #[repr(u8)] pub enum aya_log_common::ArgumentKind
pub aya_log_common::Argument::ArrU16Len8 pub aya_log_common::ArgumentKind::ArrU16Len8
pub aya_log_common::Argument::ArrU8Len16 pub aya_log_common::ArgumentKind::ArrU8Len16
pub aya_log_common::Argument::ArrU8Len4 pub aya_log_common::ArgumentKind::ArrU8Len4
pub aya_log_common::Argument::ArrU8Len6 pub aya_log_common::ArgumentKind::ArrU8Len6
pub aya_log_common::Argument::Bytes pub aya_log_common::ArgumentKind::Bytes
pub aya_log_common::Argument::DisplayHint pub aya_log_common::ArgumentKind::DisplayHint
pub aya_log_common::Argument::F32 pub aya_log_common::ArgumentKind::F32
pub aya_log_common::Argument::F64 pub aya_log_common::ArgumentKind::F64
pub aya_log_common::Argument::I16 pub aya_log_common::ArgumentKind::I16
pub aya_log_common::Argument::I32 pub aya_log_common::ArgumentKind::I32
pub aya_log_common::Argument::I64 pub aya_log_common::ArgumentKind::I64
pub aya_log_common::Argument::I8 pub aya_log_common::ArgumentKind::I8
pub aya_log_common::Argument::Ipv4Addr pub aya_log_common::ArgumentKind::Ipv4Addr
pub aya_log_common::Argument::Ipv6Addr pub aya_log_common::ArgumentKind::Ipv6Addr
pub aya_log_common::Argument::Isize pub aya_log_common::ArgumentKind::Isize
pub aya_log_common::Argument::Str pub aya_log_common::ArgumentKind::Str
pub aya_log_common::Argument::U16 pub aya_log_common::ArgumentKind::U16
pub aya_log_common::Argument::U32 pub aya_log_common::ArgumentKind::U32
pub aya_log_common::Argument::U64 pub aya_log_common::ArgumentKind::U64
pub aya_log_common::Argument::U8 pub aya_log_common::ArgumentKind::U8
pub aya_log_common::Argument::Usize pub aya_log_common::ArgumentKind::Usize
impl core::clone::Clone for aya_log_common::Argument impl core::clone::Clone for aya_log_common::ArgumentKind
pub fn aya_log_common::Argument::clone(&self) -> aya_log_common::Argument pub fn aya_log_common::ArgumentKind::clone(&self) -> aya_log_common::ArgumentKind
impl core::convert::From<aya_log_common::Argument> for u8 impl core::convert::From<aya_log_common::ArgumentKind> for u8
pub fn u8::from(enum_value: aya_log_common::Argument) -> Self pub fn u8::from(enum_value: aya_log_common::ArgumentKind) -> Self
impl core::fmt::Debug for aya_log_common::Argument impl core::fmt::Debug for aya_log_common::ArgumentKind
pub fn aya_log_common::Argument::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya_log_common::ArgumentKind::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya_log_common::Argument impl core::marker::Copy for aya_log_common::ArgumentKind
impl core::marker::Freeze for aya_log_common::Argument impl core::marker::Freeze for aya_log_common::ArgumentKind
impl core::marker::Send for aya_log_common::Argument impl core::marker::Send for aya_log_common::ArgumentKind
impl core::marker::Sync for aya_log_common::Argument impl core::marker::Sync for aya_log_common::ArgumentKind
impl core::marker::Unpin for aya_log_common::Argument impl core::marker::Unpin for aya_log_common::ArgumentKind
impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::Argument impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::ArgumentKind
impl core::panic::unwind_safe::UnwindSafe for aya_log_common::Argument impl core::panic::unwind_safe::UnwindSafe for aya_log_common::ArgumentKind
impl<T, U> core::convert::Into<U> for aya_log_common::Argument where U: core::convert::From<T> impl<T, U> core::convert::Into<U> for aya_log_common::ArgumentKind where U: core::convert::From<T>
pub fn aya_log_common::Argument::into(self) -> U pub fn aya_log_common::ArgumentKind::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::Argument where U: core::convert::Into<T> impl<T, U> core::convert::TryFrom<U> for aya_log_common::ArgumentKind where U: core::convert::Into<T>
pub type aya_log_common::Argument::Error = core::convert::Infallible pub type aya_log_common::ArgumentKind::Error = core::convert::Infallible
pub fn aya_log_common::Argument::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error> pub fn aya_log_common::ArgumentKind::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_log_common::Argument where U: core::convert::TryFrom<T> impl<T, U> core::convert::TryInto<U> for aya_log_common::ArgumentKind where U: core::convert::TryFrom<T>
pub type aya_log_common::Argument::Error = <U as core::convert::TryFrom<T>>::Error pub type aya_log_common::ArgumentKind::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_log_common::Argument::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error> pub fn aya_log_common::ArgumentKind::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_log_common::Argument where T: 'static + ?core::marker::Sized impl<T> core::any::Any for aya_log_common::ArgumentKind where T: 'static + ?core::marker::Sized
pub fn aya_log_common::Argument::type_id(&self) -> core::any::TypeId pub fn aya_log_common::ArgumentKind::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_log_common::Argument where T: ?core::marker::Sized impl<T> core::borrow::Borrow<T> for aya_log_common::ArgumentKind where T: ?core::marker::Sized
pub fn aya_log_common::Argument::borrow(&self) -> &T pub fn aya_log_common::ArgumentKind::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::Argument where T: ?core::marker::Sized impl<T> core::borrow::BorrowMut<T> for aya_log_common::ArgumentKind where T: ?core::marker::Sized
pub fn aya_log_common::Argument::borrow_mut(&mut self) -> &mut T pub fn aya_log_common::ArgumentKind::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya_log_common::Argument where T: core::clone::Clone impl<T> core::clone::CloneToUninit for aya_log_common::ArgumentKind where T: core::clone::Clone
pub unsafe fn aya_log_common::Argument::clone_to_uninit(&self, dest: *mut u8) pub unsafe fn aya_log_common::ArgumentKind::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya_log_common::Argument impl<T> core::convert::From<T> for aya_log_common::ArgumentKind
pub fn aya_log_common::Argument::from(t: T) -> T pub fn aya_log_common::ArgumentKind::from(t: T) -> T
#[repr(u8)] pub enum aya_log_common::DisplayHint #[repr(u8)] pub enum aya_log_common::DisplayHint
pub aya_log_common::DisplayHint::Default = 1 pub aya_log_common::DisplayHint::Default = 1
pub aya_log_common::DisplayHint::Ip 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::LowerMac
pub aya_log_common::DisplayHint::UpperHex pub aya_log_common::DisplayHint::UpperHex
pub aya_log_common::DisplayHint::UpperMac pub aya_log_common::DisplayHint::UpperMac
impl aya_log_common::WriteToBuf for aya_log_common::DisplayHint impl aya_log_common::Argument for aya_log_common::DisplayHint
pub fn aya_log_common::DisplayHint::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize> 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 impl core::clone::Clone for aya_log_common::DisplayHint
pub fn aya_log_common::DisplayHint::clone(&self) -> 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 impl core::cmp::Eq for aya_log_common::DisplayHint
@ -139,45 +139,90 @@ impl<T> 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) pub unsafe fn aya_log_common::Level::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya_log_common::Level impl<T> core::convert::From<T> for aya_log_common::Level
pub fn aya_log_common::Level::from(t: T) -> T pub fn aya_log_common::Level::from(t: T) -> T
#[repr(u8)] pub enum aya_log_common::RecordField #[repr(u8)] pub enum aya_log_common::RecordFieldKind
pub aya_log_common::RecordField::File pub aya_log_common::RecordFieldKind::File
pub aya_log_common::RecordField::Level pub aya_log_common::RecordFieldKind::Level
pub aya_log_common::RecordField::Line pub aya_log_common::RecordFieldKind::Line
pub aya_log_common::RecordField::Module pub aya_log_common::RecordFieldKind::Module
pub aya_log_common::RecordField::NumArgs pub aya_log_common::RecordFieldKind::NumArgs
pub aya_log_common::RecordField::Target = 1 pub aya_log_common::RecordFieldKind::Target
impl core::clone::Clone for aya_log_common::RecordField impl core::clone::Clone for aya_log_common::RecordFieldKind
pub fn aya_log_common::RecordField::clone(&self) -> aya_log_common::RecordField pub fn aya_log_common::RecordFieldKind::clone(&self) -> aya_log_common::RecordFieldKind
impl core::convert::From<aya_log_common::RecordField> for u8 impl core::convert::From<aya_log_common::RecordFieldKind> for u8
pub fn u8::from(enum_value: aya_log_common::RecordField) -> Self pub fn u8::from(enum_value: aya_log_common::RecordFieldKind) -> Self
impl core::fmt::Debug for aya_log_common::RecordField impl core::fmt::Debug for aya_log_common::RecordFieldKind
pub fn aya_log_common::RecordField::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya_log_common::RecordFieldKind::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya_log_common::RecordField impl core::marker::Copy for aya_log_common::RecordFieldKind
impl core::marker::Freeze for aya_log_common::RecordField impl core::marker::Freeze for aya_log_common::RecordFieldKind
impl core::marker::Send for aya_log_common::RecordField impl core::marker::Send for aya_log_common::RecordFieldKind
impl core::marker::Sync for aya_log_common::RecordField impl core::marker::Sync for aya_log_common::RecordFieldKind
impl core::marker::Unpin for aya_log_common::RecordField impl core::marker::Unpin for aya_log_common::RecordFieldKind
impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::RecordField impl core::panic::unwind_safe::RefUnwindSafe for aya_log_common::RecordFieldKind
impl core::panic::unwind_safe::UnwindSafe for aya_log_common::RecordField impl core::panic::unwind_safe::UnwindSafe for aya_log_common::RecordFieldKind
impl<T, U> core::convert::Into<U> for aya_log_common::RecordField where U: core::convert::From<T> impl<T, U> core::convert::Into<U> for aya_log_common::RecordFieldKind where U: core::convert::From<T>
pub fn aya_log_common::RecordField::into(self) -> U pub fn aya_log_common::RecordFieldKind::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::RecordField where U: core::convert::Into<T> impl<T, U> core::convert::TryFrom<U> for aya_log_common::RecordFieldKind where U: core::convert::Into<T>
pub type aya_log_common::RecordField::Error = core::convert::Infallible pub type aya_log_common::RecordFieldKind::Error = core::convert::Infallible
pub fn aya_log_common::RecordField::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error> pub fn aya_log_common::RecordFieldKind::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_log_common::RecordField where U: core::convert::TryFrom<T> impl<T, U> core::convert::TryInto<U> for aya_log_common::RecordFieldKind where U: core::convert::TryFrom<T>
pub type aya_log_common::RecordField::Error = <U as core::convert::TryFrom<T>>::Error pub type aya_log_common::RecordFieldKind::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_log_common::RecordField::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error> pub fn aya_log_common::RecordFieldKind::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_log_common::RecordField where T: 'static + ?core::marker::Sized impl<T> core::any::Any for aya_log_common::RecordFieldKind where T: 'static + ?core::marker::Sized
pub fn aya_log_common::RecordField::type_id(&self) -> core::any::TypeId pub fn aya_log_common::RecordFieldKind::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_log_common::RecordField where T: ?core::marker::Sized impl<T> core::borrow::Borrow<T> for aya_log_common::RecordFieldKind where T: ?core::marker::Sized
pub fn aya_log_common::RecordField::borrow(&self) -> &T pub fn aya_log_common::RecordFieldKind::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::RecordField where T: ?core::marker::Sized impl<T> core::borrow::BorrowMut<T> for aya_log_common::RecordFieldKind where T: ?core::marker::Sized
pub fn aya_log_common::RecordField::borrow_mut(&mut self) -> &mut T pub fn aya_log_common::RecordFieldKind::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya_log_common::RecordField where T: core::clone::Clone impl<T> core::clone::CloneToUninit for aya_log_common::RecordFieldKind where T: core::clone::Clone
pub unsafe fn aya_log_common::RecordField::clone_to_uninit(&self, dest: *mut u8) pub unsafe fn aya_log_common::RecordFieldKind::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya_log_common::RecordField impl<T> core::convert::From<T> for aya_log_common::RecordFieldKind
pub fn aya_log_common::RecordField::from(t: T) -> T pub fn aya_log_common::RecordFieldKind::from(t: T) -> T
pub const aya_log_common::LOG_FIELDS: usize 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 pub trait aya_log_common::DefaultFormatter
impl aya_log_common::DefaultFormatter for &str impl aya_log_common::DefaultFormatter for &str
impl aya_log_common::DefaultFormatter for bool 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 impl aya_log_common::UpperHexFormatter for usize
pub trait aya_log_common::UpperMacFormatter pub trait aya_log_common::UpperMacFormatter
impl aya_log_common::UpperMacFormatter for [u8; 6] 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<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for &[u8]
pub fn &[u8]::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for &str
pub fn &str::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for [u16; 8]
pub fn [u16; 8]::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for [u8; 16]
pub fn [u8; 16]::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for [u8; 4]
pub fn [u8; 4]::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for [u8; 6]
pub fn [u8; 6]::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for aya_log_common::DisplayHint
pub fn aya_log_common::DisplayHint::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
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<core::num::nonzero::NonZeroUsize>
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<core::num::nonzero::NonZeroUsize>
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<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for f32
pub fn f32::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for f64
pub fn f64::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for i16
pub fn i16::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for i32
pub fn i32::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for i64
pub fn i64::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for i8
pub fn i8::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for isize
pub fn isize::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for u16
pub fn u16::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for u32
pub fn u32::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for u64
pub fn u64::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for u8
pub fn u8::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
impl aya_log_common::WriteToBuf for usize
pub fn usize::write(self, buf: &mut [u8]) -> core::option::Option<core::num::nonzero::NonZeroUsize>
pub type aya_log_common::LogValueLength = u16 pub type aya_log_common::LogValueLength = u16

Loading…
Cancel
Save