Skip to content

Instantly share code, notes, and snippets.

@hillu
Last active May 24, 2025 10:43
Show Gist options
  • Select an option

  • Save hillu/4183f16f12c5a672fcfc52af68ccccc8 to your computer and use it in GitHub Desktop.

Select an option

Save hillu/4183f16f12c5a672fcfc52af68ccccc8 to your computer and use it in GitHub Desktop.
A subset of aya_log_ebpf functionality re-implemented in C
#include <linux/bpf/vmlinux.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "aya_log.h"
static size_t strlen(const char* s)
{
int i;
for (i=0; i < 255 && s[i] != 0; i++) {}
return i;
}
static size_t my_memcpy(void* d, const void* s, size_t l)
__attribute__((no_builtin("memcpy")))
{
for (size_t i=0; i < l; i++) {
((char*)d)[i] = ((char*)s)[i];
}
return l;
}
/* Add tag+length+value to buffer */
static size_t _aya_logbuf_add_tlv(char* buf, char tag, u16 len, const void* value)
{
char* start = buf;
*(buf++) = tag;
my_memcpy(buf, &len, sizeof(len));
buf += sizeof(len);
if (len > 0) {
my_memcpy(buf, value, len);
}
buf += len;
return buf - start;
}
/* Add tag+string to log buffer */
static size_t _aya_logbuf_add_ts(char* buf, char tag, const char* s)
{
return _aya_logbuf_add_tlv(buf, tag, strlen(s), s);
}
struct AYA_LOGS {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
} AYA_LOGS SEC(".maps");
struct AYA_LOG_BUF {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1);
__uint(key_size, sizeof(u32));
__uint(value_size, AYA_LOG_BUF_CAPACITY);
} AYA_LOG_BUF SEC(".maps");
static size_t _aya_log_write_header(char *buf, const char* target, u8 level, const char* module, const char* file, u32 line) {
char* b = buf;
b += _aya_logbuf_add_ts(b, AYA_TARGET, target);
b += _aya_logbuf_add_tlv(b, AYA_LEVEL, 1, &level);
b += _aya_logbuf_add_ts(b, AYA_MODULE, module);
b += _aya_logbuf_add_ts(b, AYA_FILE, file);
b += _aya_logbuf_add_tlv(b, AYA_LINE, 4, &line);
u64 v2 = 1;
b += _aya_logbuf_add_tlv(b, AYA_NUMARGS, 8, &v2);
return b - buf;
}
static void aya_log_print(void *ctx, const char* target, u8 level, const char* module, const char* file, u32 line, const char* message) {
size_t i = 0;
char* buf = bpf_map_lookup_elem(&AYA_LOG_BUF, &i);
if (!buf) return;
u64 sz = strlen(message);
char* b = buf;
b += _aya_log_write_header(b, target, level, module, file, line);
b += _aya_logbuf_add_tlv(b, AYA_TYPE_STR, sz, message);
bpf_perf_event_output(ctx, &AYA_LOGS, BPF_F_CURRENT_CPU, buf, b-buf);
}
#ifndef AYA_LOG_H
#define AYA_LOG_H
#ifndef AYA_LOG_TARGET_NAME
#error "AYA_LOG_TARGET_NAME needs to be defined"
#endif
/* see aya_log_common::Level */
enum {
AYA_ERROR = 1,
AYA_WARN,
AYA_INFO,
AYA_DEBUG,
AYA_TRACE,
};
/* see aya_log_common::RecordField */
enum {
AYA_TARGET = 1, // string
AYA_LEVEL, // u8
AYA_MODULE, // string
AYA_FILE, // string
AYA_LINE, // u32
AYA_NUMARGS, // usize_t
};
/* see aya_log_common::Argument */
enum {
AYA_TYPE_DISPLAYHINT = 0,
AYA_TYPE_I8,
AYA_TYPE_I16,
AYA_TYPE_I32,
AYA_TYPE_I64,
AYA_TYPE_ISIZE,
AYA_TYPE_U8,
AYA_TYPE_U16,
AYA_TYPE_U32,
AYA_TYPE_U64,
AYA_TYPE_USIZE,
AYA_TYPE_F32,
AYA_TYPE_F64,
AYA_TYPE_IPV4ADDR,
AYA_TYPE_IPV6ADDR,
AYA_TYPE_ARRU8LEN4,
AYA_TYPE_ARRU8LEN6,
AYA_TYPE_ARRU8LEN16,
AYA_TYPE_ARRU16LEN8,
AYA_TYPE_BYTES,
AYA_TYPE_STR,
};
#define AYA_LOG_BUF_CAPACITY 8192
static void aya_log_print(void *ctx, const char* target, u8 level, const char* module, const char* file, u32 line, const char* message);
#define AYA_LOG_PRINT(level, message) \
aya_log_print(ctx, AYA_LOG_TARGET_NAME, level, __FUNCTION__, __FILE__, __LINE__, message)
#endif /* AYA_LOG_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment