aya-log-ebpf: zero copy!

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

@ -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: <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>;
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<N> where N is
// mem::size_of<$type>, which is a compile-time constant.
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
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<L, R> {
Left(L),
Right(R),
}
impl WriteToBuf for IpAddr {
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
impl<L, R> AsRef<[u8]> for Either<L, R>
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<NonZeroUsize> {
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<N> where N is 16, which is a
// compile-time constant.
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
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<NonZeroUsize> {
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<N> where N is 16, which is a
// compile-time constant.
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
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<N> where N is 16, which is a
// compile-time constant.
#[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 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<N> where N is 6, which is a
// compile-time constant.
#[inline(never)]
fn write(self, buf: &mut [u8]) -> Option<NonZeroUsize> {
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: <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 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: <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 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<N> where N is 1, which is a
// compile-time constant.
#[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 &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<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)]
#[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<NonZeroUsize> {
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<Self> {
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)
}

@ -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<TokenStream>) -> Result<TokenStre
for fragment in fragments {
match fragment {
Fragment::Literal(s) => 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<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 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(())
})();
})
}

@ -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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(mut buf: &[u8], logger: &T) -> Result<(), ()> {
let mut full_log_msg = String::new();
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)?;
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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: ?Sized + Log>(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<T: Pod>(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<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::*;
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 len = write_record_header(
&mut buf,

@ -7,31 +7,16 @@ 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_log_common::LogValueLength;
use aya_ebpf::maps::RingBuf;
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<LogBuf> = 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
// test/integration-test/Cargo.toml.
#[cfg_attr(target_arch = "bpf", map)]
pub static AYA_LOGS: RingBuf = RingBuf::with_byte_size((LOG_BUF_CAPACITY as u32) << 4, 0);
pub static AYA_LOGS: RingBuf = RingBuf::with_byte_size(1 << 17 /* 128 KiB */, 0);
}

@ -62,11 +62,17 @@ pub fn test_log(ctx: ProbeContext) {
warn!(&ctx, "hex lc: {:x}, hex uc: {:X}", hex, hex);
let hex = [0xde, 0xad, 0xbe, 0xef].as_slice();
debug!(&ctx, "hex lc: {:x}, hex uc: {:X}", hex, hex);
let len = 42;
let size = 43;
let slice = 44;
let record = 45;
debug!(&ctx, "{} {} {} {}", len, size, slice, record);
let header = 42;
let tmp = 43;
let kind = 44;
let value = 45;
let size = 46;
let op = 47;
let buf = 48;
debug!(
&ctx,
"{} {} {} {} {} {} {}", header, tmp, kind, value, size, op, buf
);
// Testing compilation only.
if false {

@ -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<aya_log_common::Argument> 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<T, U> core::convert::Into<U> for aya_log_common::Argument where U: core::convert::From<T>
pub fn aya_log_common::Argument::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::Argument where U: core::convert::Into<T>
pub type aya_log_common::Argument::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>
impl<T, U> core::convert::TryInto<U> for aya_log_common::Argument where U: core::convert::TryFrom<T>
pub type aya_log_common::Argument::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>
impl<T> 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<T> core::borrow::Borrow<T> for aya_log_common::Argument where T: ?core::marker::Sized
pub fn aya_log_common::Argument::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::Argument where T: ?core::marker::Sized
pub fn aya_log_common::Argument::borrow_mut(&mut self) -> &mut T
impl<T> 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<T> core::convert::From<T> 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<aya_log_common::ArgumentKind> 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<T, U> core::convert::Into<U> for aya_log_common::ArgumentKind where U: core::convert::From<T>
pub fn aya_log_common::ArgumentKind::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::ArgumentKind where U: core::convert::Into<T>
pub type aya_log_common::ArgumentKind::Error = core::convert::Infallible
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::ArgumentKind where U: core::convert::TryFrom<T>
pub type aya_log_common::ArgumentKind::Error = <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::ArgumentKind where T: 'static + ?core::marker::Sized
pub fn aya_log_common::ArgumentKind::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_log_common::ArgumentKind where T: ?core::marker::Sized
pub fn aya_log_common::ArgumentKind::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::ArgumentKind where T: ?core::marker::Sized
pub fn aya_log_common::ArgumentKind::borrow_mut(&mut self) -> &mut T
impl<T> 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<T> core::convert::From<T> 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<core::num::nonzero::NonZeroUsize>
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<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)
impl<T> core::convert::From<T> 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<aya_log_common::RecordField> 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<T, U> core::convert::Into<U> for aya_log_common::RecordField where U: core::convert::From<T>
pub fn aya_log_common::RecordField::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::RecordField where U: core::convert::Into<T>
pub type aya_log_common::RecordField::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>
impl<T, U> core::convert::TryInto<U> for aya_log_common::RecordField where U: core::convert::TryFrom<T>
pub type aya_log_common::RecordField::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>
impl<T> 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<T> core::borrow::Borrow<T> for aya_log_common::RecordField where T: ?core::marker::Sized
pub fn aya_log_common::RecordField::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::RecordField where T: ?core::marker::Sized
pub fn aya_log_common::RecordField::borrow_mut(&mut self) -> &mut T
impl<T> 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<T> core::convert::From<T> 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<aya_log_common::RecordFieldKind> 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<T, U> core::convert::Into<U> for aya_log_common::RecordFieldKind where U: core::convert::From<T>
pub fn aya_log_common::RecordFieldKind::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log_common::RecordFieldKind where U: core::convert::Into<T>
pub type aya_log_common::RecordFieldKind::Error = core::convert::Infallible
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::RecordFieldKind where U: core::convert::TryFrom<T>
pub type aya_log_common::RecordFieldKind::Error = <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::RecordFieldKind where T: 'static + ?core::marker::Sized
pub fn aya_log_common::RecordFieldKind::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_log_common::RecordFieldKind where T: ?core::marker::Sized
pub fn aya_log_common::RecordFieldKind::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_log_common::RecordFieldKind where T: ?core::marker::Sized
pub fn aya_log_common::RecordFieldKind::borrow_mut(&mut self) -> &mut T
impl<T> 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<T> core::convert::From<T> 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<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

Loading…
Cancel
Save