mirror of https://github.com/aya-rs/aya
Merge pull request #350 from dave-tucker/monorepo
Bring aya-log into aya, creating a Monorepopull/353/head
commit
f37a51433f
@ -1,4 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": ["Cargo.toml", "bpf/Cargo.toml", "test/integration-ebpf/Cargo.toml"],
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
"rust-analyzer.checkOnSave.allTargets": false,
|
||||
"rust-analyzer.checkOnSave.command": "clippy"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": ["Cargo.toml", "bpf/Cargo.toml", "test/integration-ebpf/Cargo.toml"],
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
"rust-analyzer.checkOnSave.allTargets": false,
|
||||
"rust-analyzer.checkOnSave.command": "clippy"
|
||||
}
|
||||
|
@ -1,3 +1,22 @@
|
||||
[workspace]
|
||||
members = ["aya", "aya-gen", "test/integration-test", "test/integration-test-macros", "xtask"]
|
||||
default-members = ["aya", "aya-gen"]
|
||||
members = [
|
||||
"aya", "aya-gen", "aya-log", "aya-log-common", "test/integration-test", "test/integration-test-macros", "xtask",
|
||||
# macros
|
||||
"aya-bpf-macros", "aya-log-ebpf-macros",
|
||||
# ebpf crates
|
||||
"bpf/aya-bpf", "bpf/aya-bpf-bindings", "bpf/aya-log-ebpf", "test/integration-ebpf"
|
||||
]
|
||||
default-members = ["aya", "aya-gen", "aya-log", "aya-bpf-macros", "aya-log-ebpf-macros"]
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
[profile.dev.package.integration-ebpf]
|
||||
opt-level = 2
|
||||
overflow-checks = false
|
||||
|
||||
[profile.release.package.integration-ebpf]
|
||||
debug = 2
|
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "aya-log-common"
|
||||
version = "0.1.11-dev.0"
|
||||
description = "A logging library for eBPF programs."
|
||||
keywords = ["ebpf", "bpf", "log", "logging"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
authors = ["The Aya Contributors"]
|
||||
repository = "https://github.com/aya-rs/aya-log"
|
||||
documentation = "https://docs.rs/aya-log"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
userspace = [ "aya" ]
|
||||
|
||||
[dependencies]
|
||||
aya = { path = "../aya", version = "0.11.0", optional=true }
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
@ -0,0 +1 @@
|
||||
shared-version = true
|
@ -0,0 +1,185 @@
|
||||
#![no_std]
|
||||
|
||||
use core::{cmp, mem, ptr};
|
||||
|
||||
pub const LOG_BUF_CAPACITY: usize = 8192;
|
||||
|
||||
pub const LOG_FIELDS: usize = 7;
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
|
||||
pub enum Level {
|
||||
/// The "error" level.
|
||||
///
|
||||
/// Designates very serious errors.
|
||||
Error = 1,
|
||||
/// The "warn" level.
|
||||
///
|
||||
/// Designates hazardous situations.
|
||||
Warn,
|
||||
/// The "info" level.
|
||||
///
|
||||
/// Designates useful information.
|
||||
Info,
|
||||
/// The "debug" level.
|
||||
///
|
||||
/// Designates lower priority information.
|
||||
Debug,
|
||||
/// The "trace" level.
|
||||
///
|
||||
/// Designates very low priority, often extremely verbose, information.
|
||||
Trace,
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum RecordField {
|
||||
Target = 1,
|
||||
Level,
|
||||
Module,
|
||||
File,
|
||||
Line,
|
||||
NumArgs,
|
||||
Log,
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum ArgType {
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
Isize,
|
||||
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
Usize,
|
||||
|
||||
F32,
|
||||
F64,
|
||||
|
||||
Str,
|
||||
}
|
||||
|
||||
#[cfg(feature = "userspace")]
|
||||
mod userspace {
|
||||
use super::*;
|
||||
|
||||
unsafe impl aya::Pod for RecordField {}
|
||||
unsafe impl aya::Pod for ArgType {}
|
||||
}
|
||||
|
||||
struct TagLenValue<'a, T> {
|
||||
tag: T,
|
||||
value: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a, T> TagLenValue<'a, T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(tag: T, value: &'a [u8]) -> TagLenValue<'a, T> {
|
||||
TagLenValue { tag, value }
|
||||
}
|
||||
|
||||
pub(crate) fn write(&self, mut buf: &mut [u8]) -> Result<usize, ()> {
|
||||
let size = mem::size_of::<T>() + mem::size_of::<usize>() + self.value.len();
|
||||
let remaining = cmp::min(buf.len(), LOG_BUF_CAPACITY);
|
||||
// Check if the size doesn't exceed the buffer bounds.
|
||||
if size > remaining {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.tag) };
|
||||
buf = &mut buf[mem::size_of::<T>()..];
|
||||
|
||||
unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.value.len()) };
|
||||
buf = &mut buf[mem::size_of::<usize>()..];
|
||||
|
||||
let len = cmp::min(buf.len(), self.value.len());
|
||||
// The verifier isn't happy with `len` being unbounded, so compare it
|
||||
// with `LOG_BUF_CAPACITY`.
|
||||
if len > LOG_BUF_CAPACITY {
|
||||
return Err(());
|
||||
}
|
||||
buf[..len].copy_from_slice(&self.value[..len]);
|
||||
Ok(size)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WriteToBuf {
|
||||
#[allow(clippy::result_unit_err)]
|
||||
fn write(&self, buf: &mut [u8]) -> Result<usize, ()>;
|
||||
}
|
||||
|
||||
macro_rules! impl_write_to_buf {
|
||||
($type:ident, $arg_type:expr) => {
|
||||
impl WriteToBuf for $type {
|
||||
fn write(&self, buf: &mut [u8]) -> Result<usize, ()> {
|
||||
TagLenValue::<ArgType>::new($arg_type, &self.to_ne_bytes()).write(buf)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_write_to_buf!(i8, ArgType::I8);
|
||||
impl_write_to_buf!(i16, ArgType::I16);
|
||||
impl_write_to_buf!(i32, ArgType::I32);
|
||||
impl_write_to_buf!(i64, ArgType::I64);
|
||||
impl_write_to_buf!(i128, ArgType::I128);
|
||||
impl_write_to_buf!(isize, ArgType::Isize);
|
||||
|
||||
impl_write_to_buf!(u8, ArgType::U8);
|
||||
impl_write_to_buf!(u16, ArgType::U16);
|
||||
impl_write_to_buf!(u32, ArgType::U32);
|
||||
impl_write_to_buf!(u64, ArgType::U64);
|
||||
impl_write_to_buf!(u128, ArgType::U128);
|
||||
impl_write_to_buf!(usize, ArgType::Usize);
|
||||
|
||||
impl_write_to_buf!(f32, ArgType::F32);
|
||||
impl_write_to_buf!(f64, ArgType::F64);
|
||||
|
||||
impl WriteToBuf for str {
|
||||
fn write(&self, buf: &mut [u8]) -> Result<usize, ()> {
|
||||
TagLenValue::<ArgType>::new(ArgType::Str, self.as_bytes()).write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::result_unit_err)]
|
||||
#[doc(hidden)]
|
||||
#[inline(always)]
|
||||
pub fn write_record_header(
|
||||
buf: &mut [u8],
|
||||
target: &str,
|
||||
level: Level,
|
||||
module: &str,
|
||||
file: &str,
|
||||
line: u32,
|
||||
num_args: usize,
|
||||
) -> Result<usize, ()> {
|
||||
let mut size = 0;
|
||||
for attr in [
|
||||
TagLenValue::<RecordField>::new(RecordField::Target, target.as_bytes()),
|
||||
TagLenValue::<RecordField>::new(RecordField::Level, &(level as usize).to_ne_bytes()),
|
||||
TagLenValue::<RecordField>::new(RecordField::Module, module.as_bytes()),
|
||||
TagLenValue::<RecordField>::new(RecordField::File, file.as_bytes()),
|
||||
TagLenValue::<RecordField>::new(RecordField::Line, &line.to_ne_bytes()),
|
||||
TagLenValue::<RecordField>::new(RecordField::NumArgs, &num_args.to_ne_bytes()),
|
||||
] {
|
||||
size += attr.write(&mut buf[size..])?;
|
||||
}
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
#[allow(clippy::result_unit_err)]
|
||||
#[doc(hidden)]
|
||||
pub fn write_record_message(buf: &mut [u8], msg: &str) -> Result<usize, ()> {
|
||||
TagLenValue::<RecordField>::new(RecordField::Log, msg.as_bytes()).write(buf)
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "aya-log-ebpf-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = "1.0"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
@ -0,0 +1,189 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
Error, Expr, LitStr, Result, Token,
|
||||
};
|
||||
|
||||
pub(crate) struct LogArgs {
|
||||
pub(crate) ctx: Expr,
|
||||
pub(crate) target: Option<Expr>,
|
||||
pub(crate) level: Option<Expr>,
|
||||
pub(crate) format_string: LitStr,
|
||||
pub(crate) formatting_args: Option<Punctuated<Expr, Token![,]>>,
|
||||
}
|
||||
|
||||
mod kw {
|
||||
syn::custom_keyword!(target);
|
||||
}
|
||||
|
||||
impl Parse for LogArgs {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let ctx: Expr = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
// Parse `target: &str`, which is an optional argument.
|
||||
let target: Option<Expr> = if input.peek(kw::target) {
|
||||
input.parse::<kw::target>()?;
|
||||
input.parse::<Token![:]>()?;
|
||||
let t: Expr = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
Some(t)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Check whether the next token is `format_string: &str` (which i
|
||||
// always provided) or `level` (which is an optional expression).
|
||||
// If `level` is provided, it comes before `format_string`.
|
||||
let (level, format_string): (Option<Expr>, LitStr) = if input.peek(LitStr) {
|
||||
// Only `format_string` is provided.
|
||||
(None, input.parse()?)
|
||||
} else {
|
||||
// Both `level` and `format_string` are provided.
|
||||
let level: Expr = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
let format_string: LitStr = input.parse()?;
|
||||
(Some(level), format_string)
|
||||
};
|
||||
|
||||
// Parse variadic arguments.
|
||||
let formatting_args: Option<Punctuated<Expr, Token![,]>> = if input.is_empty() {
|
||||
None
|
||||
} else {
|
||||
input.parse::<Token![,]>()?;
|
||||
Some(Punctuated::parse_terminated(input)?)
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
ctx,
|
||||
target,
|
||||
level,
|
||||
format_string,
|
||||
formatting_args,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn log(args: LogArgs, level: Option<TokenStream>) -> Result<TokenStream> {
|
||||
let ctx = args.ctx;
|
||||
let target = match args.target {
|
||||
Some(t) => quote! { #t },
|
||||
None => quote! { module_path!() },
|
||||
};
|
||||
let lvl: TokenStream = if let Some(l) = level {
|
||||
l
|
||||
} else if let Some(l) = args.level {
|
||||
quote! { #l }
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
args.format_string.span(),
|
||||
"missing `level` argument: try passing an `aya_log_ebpf::Level` value",
|
||||
));
|
||||
};
|
||||
let format_string = args.format_string;
|
||||
|
||||
let (num_args, write_args) = match args.formatting_args {
|
||||
Some(formatting_args) => {
|
||||
let formatting_exprs = formatting_args.iter();
|
||||
let num_args = formatting_exprs.len();
|
||||
|
||||
let write_args = quote! {{
|
||||
use ::aya_log_ebpf::WriteToBuf;
|
||||
Ok::<_, ()>(record_len) #( .and_then(|record_len| {
|
||||
if record_len >= buf.buf.len() {
|
||||
return Err(());
|
||||
}
|
||||
{ #formatting_exprs }.write(&mut buf.buf[record_len..]).map(|len| record_len + len)
|
||||
}) )*
|
||||
}};
|
||||
|
||||
(num_args, write_args)
|
||||
}
|
||||
None => (0, quote! {}),
|
||||
};
|
||||
|
||||
// The way of writing to the perf buffer is different depending on whether
|
||||
// we have variadic arguments or not.
|
||||
let write_to_perf_buffer = if num_args > 0 {
|
||||
// Writing with variadic arguments.
|
||||
quote! {
|
||||
if let Ok(record_len) = #write_args {
|
||||
unsafe { ::aya_log_ebpf::AYA_LOGS.output(
|
||||
#ctx,
|
||||
&buf.buf[..record_len], 0
|
||||
)}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Writing with no variadic arguments.
|
||||
quote! {
|
||||
unsafe { ::aya_log_ebpf::AYA_LOGS.output(
|
||||
#ctx,
|
||||
&buf.buf[..record_len], 0
|
||||
)}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
{
|
||||
if let Some(buf_ptr) = unsafe { ::aya_log_ebpf::AYA_LOG_BUF.get_ptr_mut(0) } {
|
||||
let buf = unsafe { &mut *buf_ptr };
|
||||
if let Ok(header_len) = ::aya_log_ebpf::write_record_header(
|
||||
&mut buf.buf,
|
||||
#target,
|
||||
#lvl,
|
||||
module_path!(),
|
||||
file!(),
|
||||
line!(),
|
||||
#num_args,
|
||||
) {
|
||||
if let Ok(message_len) = ::aya_log_ebpf::write_record_message(
|
||||
&mut buf.buf[header_len..],
|
||||
#format_string,
|
||||
) {
|
||||
let record_len = header_len + message_len;
|
||||
|
||||
#write_to_perf_buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn error(args: LogArgs) -> Result<TokenStream> {
|
||||
log(
|
||||
args,
|
||||
Some(quote! { ::aya_log_ebpf::macro_support::Level::Error }),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn warn(args: LogArgs) -> Result<TokenStream> {
|
||||
log(
|
||||
args,
|
||||
Some(quote! { ::aya_log_ebpf::macro_support::Level::Warn }),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn info(args: LogArgs) -> Result<TokenStream> {
|
||||
log(
|
||||
args,
|
||||
Some(quote! { ::aya_log_ebpf::macro_support::Level::Info }),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn debug(args: LogArgs) -> Result<TokenStream> {
|
||||
log(
|
||||
args,
|
||||
Some(quote! { ::aya_log_ebpf::macro_support::Level::Debug }),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn trace(args: LogArgs) -> Result<TokenStream> {
|
||||
log(
|
||||
args,
|
||||
Some(quote! { ::aya_log_ebpf::macro_support::Level::Trace }),
|
||||
)
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
use proc_macro::TokenStream;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
mod expand;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn log(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::log(args, None)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn error(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::error(args)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn warn(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::warn(args)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn info(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::info(args)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn debug(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::debug(args)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn trace(args: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as expand::LogArgs);
|
||||
expand::trace(args)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "aya-log"
|
||||
version = "0.1.11-dev.0"
|
||||
description = "A logging library for eBPF programs."
|
||||
keywords = ["ebpf", "bpf", "log", "logging"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
authors = ["The Aya Contributors"]
|
||||
repository = "https://github.com/aya-rs/aya-log"
|
||||
readme = "README.md"
|
||||
documentation = "https://docs.rs/aya-log"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
aya = { path = "../aya", version = "0.11.0", features=["async_tokio"] }
|
||||
aya-log-common = { path = "../aya-log-common", version = "0.1.11-dev.0", features=["userspace"] }
|
||||
dyn-fmt = "0.3.0"
|
||||
thiserror = "1"
|
||||
log = "0.4"
|
||||
bytes = "1.1"
|
||||
tokio = { version = "1.2.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
simplelog = "0.12"
|
||||
testing_logger = "0.1.1"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
@ -0,0 +1,73 @@
|
||||
# aya-log - a logging library for eBPF programs
|
||||
|
||||
## Overview
|
||||
|
||||
`aya-log` is a logging library for eBPF programs written using [aya]. Think of
|
||||
it as the [log] crate for eBPF.
|
||||
|
||||
## Installation
|
||||
|
||||
### User space
|
||||
|
||||
Add `aya-log` to `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
aya-log = { git = "https://github.com/aya-rs/aya-log", branch = "main" }
|
||||
```
|
||||
|
||||
### eBPF side
|
||||
|
||||
Add `aya-log-ebpf` to `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
aya-log-ebpf = { git = "https://github.com/aya-rs/aya-log", branch = "main" }
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Here's an example that uses `aya-log` in conjunction with the [simplelog] crate
|
||||
to log eBPF messages to the terminal.
|
||||
|
||||
### User space code
|
||||
|
||||
```rust
|
||||
use simplelog::{ColorChoice, ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
|
||||
use aya_log::BpfLogger;
|
||||
|
||||
TermLogger::init(
|
||||
LevelFilter::Debug,
|
||||
ConfigBuilder::new()
|
||||
.set_target_level(LevelFilter::Error)
|
||||
.set_location_level(LevelFilter::Error)
|
||||
.build(),
|
||||
TerminalMode::Mixed,
|
||||
ColorChoice::Auto,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Will log using the default logger, which is TermLogger in this case
|
||||
BpfLogger::init(&mut bpf).unwrap();
|
||||
```
|
||||
|
||||
### eBPF code
|
||||
|
||||
```rust
|
||||
use aya_log_ebpf::info;
|
||||
|
||||
fn try_xdp_firewall(ctx: XdpContext) -> Result<u32, ()> {
|
||||
if let Some(port) = tcp_dest_port(&ctx)? {
|
||||
if block_port(port) {
|
||||
info!(&ctx, "❌ blocked incoming connection on port: {}", port);
|
||||
return Ok(XDP_DROP);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(XDP_PASS)
|
||||
}
|
||||
```
|
||||
|
||||
[aya]: https://github.com/aya-rs/aya
|
||||
[log]: https://docs.rs/log
|
||||
[simplelog]: https://docs.rs/simplelog
|
@ -0,0 +1 @@
|
||||
shared-version = true
|
@ -0,0 +1,6 @@
|
||||
[build]
|
||||
target-dir = "../target"
|
||||
target = "bpfel-unknown-none"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
@ -1,2 +0,0 @@
|
||||
[workspace]
|
||||
members = ["aya-bpf", "aya-bpf-macros", "aya-bpf-bindings"]
|
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "aya-log-ebpf"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
aya-bpf = { path = "../aya-bpf" }
|
||||
aya-log-common = { path = "../../aya-log-common" }
|
||||
aya-log-ebpf-macros = { path = "../../aya-log-ebpf-macros" }
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
@ -0,0 +1,29 @@
|
||||
#![no_std]
|
||||
use aya_bpf::{
|
||||
macros::map,
|
||||
maps::{PerCpuArray, PerfEventByteArray},
|
||||
};
|
||||
pub use aya_log_common::{
|
||||
write_record_header, write_record_message, Level, WriteToBuf, LOG_BUF_CAPACITY,
|
||||
};
|
||||
pub use aya_log_ebpf_macros::{debug, error, info, log, trace, warn};
|
||||
|
||||
#[doc(hidden)]
|
||||
#[repr(C)]
|
||||
pub struct LogBuf {
|
||||
pub buf: [u8; LOG_BUF_CAPACITY],
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[map]
|
||||
pub static mut AYA_LOG_BUF: PerCpuArray<LogBuf> = PerCpuArray::with_max_entries(1, 0);
|
||||
|
||||
#[doc(hidden)]
|
||||
#[map]
|
||||
pub static mut AYA_LOGS: PerfEventByteArray = PerfEventByteArray::new(0);
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod macro_support {
|
||||
pub use aya_log_common::{Level, LOG_BUF_CAPACITY};
|
||||
pub use aya_log_ebpf_macros::log;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
@ -1 +0,0 @@
|
||||
../rustfmt.toml
|
@ -1,3 +1,3 @@
|
||||
[build]
|
||||
publish = "site"
|
||||
command = "rustup toolchain install nightly && cargo xtask docs"
|
||||
command = "rustup toolchain install nightly -c rust-src && cargo xtask docs"
|
||||
|
@ -0,0 +1,6 @@
|
||||
pre-release-commit-message = "{crate_name}: release version {{version}}"
|
||||
post-release-commit-message = "{crate_name}: start next development iteration {{next_version}}"
|
||||
consolidate-pushes = true
|
||||
consolidate-commits = true
|
||||
dev-version = true
|
||||
dev-version-ext = "dev.0"
|
Loading…
Reference in New Issue