{"id":49112432,"url":"https://github.com/false-systems/tapio","last_synced_at":"2026-04-21T05:32:12.822Z","repository":{"id":303489321,"uuid":"1015294703","full_name":"false-systems/tapio","owner":"false-systems","description":"Edge Intelligence for Kubernetes  eBPF-based agent that captures kernel-level events, filters to anomalies at the edge","archived":false,"fork":false,"pushed_at":"2026-04-03T11:55:25.000Z","size":49484,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T16:37:03.832Z","etag":null,"topics":["debugging","devops","ebpf","kubernetes","observability"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/false-systems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-07T09:38:24.000Z","updated_at":"2026-04-03T11:55:27.000Z","dependencies_parsed_at":"2025-08-20T23:28:21.476Z","dependency_job_id":"8d4671b1-714d-419e-bd7d-1e3edde6b130","html_url":"https://github.com/false-systems/tapio","commit_stats":null,"previous_names":["yairfalse/tapio","false-systems/tapio"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/false-systems/tapio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/false-systems%2Ftapio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/false-systems%2Ftapio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/false-systems%2Ftapio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/false-systems%2Ftapio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/false-systems","download_url":"https://codeload.github.com/false-systems/tapio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/false-systems%2Ftapio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32078791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T02:38:07.213Z","status":"ssl_error","status_checked_at":"2026-04-21T02:38:06.559Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debugging","devops","ebpf","kubernetes","observability"],"created_at":"2026-04-21T05:32:12.041Z","updated_at":"2026-04-21T05:32:12.817Z","avatar_url":"https://github.com/false-systems.png","language":"Rust","readme":"\u003cp align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003ccode\u003eT A P I O\u003c/code\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  eBPF kernel observer for Kubernetes\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"https://img.shields.io/badge/rust-2024%20edition-f74c00\" alt=\"Rust\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/ebpf-kernel%205.8%2B-orange\" alt=\"eBPF\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-Apache%202.0-blue\" alt=\"License\"\u003e\n\u003c/p\u003e\n\n---\n\nFour eBPF programs attach to kernel tracepoints. Events flow through ring buffers to Rust userspace, where anomaly detection filters noise. Anomalies are enriched with Kubernetes pod context and emitted as [FALSE Protocol](https://github.com/false-systems) occurrences.\n\n```\nKernel tracepoints              Rust userspace                   Sinks\n────────────────                ──────────────                   ─────\ninet_sock_set_state ──┐\ntcp_receive_reset  ───┤         parse\ntcp_retransmit_skb ───┼── ring  filter (anomaly?)  enrich ──►   stdout\n                      │  buffer                    (kube-rs)    file (.tapio/)\nsched_process_exit ───┤                                         POLKU (planned)\noom/mark_victim    ───┤                                         Grafana (planned)\n                      │\nblock_rq_issue     ───┤\nblock_rq_complete  ───┤\n                      │\nperf_event counters ──┘\n```\n\n\u003e *Tapio* — Finnish spirit of the forest. Part of [False Systems](https://github.com/false-systems): TAPIO (eBPF edge) → POLKU (protocol hub) → AHTI (intelligence).\n\n---\n\n## Observers\n\n| Observer | Tracepoints | Anomalies |\n|----------|------------|-----------|\n| Network | `inet_sock_set_state`, `tcp_receive_reset`, `tcp_retransmit_skb` | `kernel.network.connection_refused`, `kernel.network.connection_timeout`, `kernel.network.retransmit_spike`, `kernel.network.rtt_degradation`, `kernel.network.rst_storm` |\n| Container | `sched_process_exit`, `oom/mark_victim` | `kernel.container.oom_kill`, `kernel.container.abnormal_exit` |\n| Storage | `block_rq_issue`, `block_rq_complete` | `kernel.storage.io_error`, `kernel.storage.latency_spike` |\n| Node PMC | `perf_event` (cycles, instructions, stalls) | `kernel.node.cpu_stall`, `kernel.node.memory_pressure`, `kernel.node.ipc_degradation` |\n\nEdge filtering happens at two levels. The storage observer filters in BPF — only I/O errors and latency spikes cross to userspace. The container observer filters in BPF for abnormal exits (non-zero exit code or signal). The network observer emits on state transitions and anomalies; Rust classifies retransmit spikes, RTT degradation, and connection failures. The PMC observer sends all samples; Rust detects IPC degradation and memory stalls.\n\n---\n\n## Output\n\nOccurrences carry raw kernel data. TAPIO fills factual fields (error code, message, data) but not reasoning fields — those are for downstream consumers like [AHTI](https://github.com/false-systems/ahti).\n\n```json\n{\n  \"id\": \"01JA1B2C3D4E5F6G7H8J9K0L1M\",\n  \"timestamp\": \"2026-04-03T14:23:01.042Z\",\n  \"source\": \"tapio\",\n  \"type\": \"kernel.container.oom_kill\",\n  \"protocol_version\": \"1.0\",\n  \"severity\": \"critical\",\n  \"outcome\": \"failure\",\n  \"error\": {\n    \"code\": \"OOM_KILL\",\n    \"message\": \"OOM kill pid=1234 (usage=512MB, limit=0MB)\"\n  },\n  \"context\": {\n    \"node\": \"worker-3\",\n    \"namespace\": \"default\",\n    \"entities\": [\n      { \"kind\": \"pod\", \"id\": \"default/checkout-api-7f8b9\", \"name\": \"checkout-api-7f8b9\" },\n      { \"kind\": \"deployment\", \"id\": \"default/checkout-api\", \"name\": \"checkout-api\" }\n    ]\n  },\n  \"data\": {\n    \"pid\": 1234,\n    \"tid\": 1234,\n    \"exit_code\": 137,\n    \"signal\": 9,\n    \"memory_usage_bytes\": 536870912,\n    \"memory_limit_bytes\": 0,\n    \"cgroup_id\": 8429,\n    \"timestamp_ns\": 1743691381042000000\n  }\n}\n```\n\nNote: `memory_limit_bytes` is 0 for OOM kills — the BPF tracepoint doesn't expose the cgroup limit. `context` is populated when K8s enrichment is enabled (`NODE_NAME` set).\n\n---\n\n## CLI\n\n```bash\ntapio status                    # observer status, event rates\ntapio watch                     # live anomaly stream\ntapio watch --network           # filter by observer\ntapio watch --json              # machine-readable output\ntapio recent                    # last 20 anomalies\ntapio recent --since 5m         # time window\ntapio health                    # node health across all observers\ntapio health network            # drill into one observer\n```\n\nThe CLI reads from `.tapio/occurrences/*.json` — decoupled from the agent process. Override with `--data-dir` or `TAPIO_DATA_DIR`.\n\n---\n\n## Agent\n\n```bash\ntapio-agent --sink=stdout                  # JSON lines to stdout\ntapio-agent --sink=file                    # .tapio/occurrences/*.json\ntapio-agent --sink=stdout --sink=file      # both\ntapio-agent --ebpf-dir /opt/tapio/ebpf    # compiled .o location\n```\n\nRequires `CAP_BPF` + `CAP_PERFMON` + `CAP_NET_ADMIN`. Runs as a privileged DaemonSet. Set `NODE_NAME` via the Downward API for K8s enrichment.\n\n---\n\n## Building\n\n```bash\ncargo build --release -p tapio-agent    # ~8MB, LTO + strip + opt-level=z + panic=abort\ncargo build --release -p tapio-cli      # runs anywhere (no eBPF dependency)\ncargo test --workspace                  # 61 tests\ncargo clippy --workspace --all-targets -- -D warnings\n```\n\neBPF programs are compiled separately — all four are required:\n\n```bash\nfor prog in network_monitor container_monitor storage_monitor node_pmc_monitor; do\n  clang -O2 -g -target bpf -D__TARGET_ARCH_x86 -I ebpf/headers \\\n    -c ebpf/${prog}.c -o /opt/tapio/ebpf/${prog}.o\ndone\n```\n\nRust edition 2024, MSRV 1.85. The agent requires Linux with kernel 5.8+ and BTF. The CLI runs on any platform.\n\n---\n\n## Architecture\n\n```\ntapio-common/     #[repr(C)] event structs, kernel.* types, FALSE Protocol, Sink trait\ntapio-agent/      DaemonSet — eBPF load → ring buffer → parse → filter → enrich → emit\ntapio-cli/        CLI commands, reads .tapio/occurrences/\nebpf/             4 C programs + shared headers\n```\n\nThe BPF/Rust boundary is defined by packed C structs mirrored in `tapio-common/src/ebpf.rs`. Size assertions enforce layout agreement at compile time. CO-RE (`preserve_access_index` + `bpf_core_read`) handles kernel struct field access across versions; tracepoint argument structs use stable kernel ABI layouts.\n\nSinks implement `tapio_common::sink::Sink` (sync `send`/`flush`/`name`). Current: `StdoutSink`, `FileSink`, `PolkuSink` (HTTP POST with batching), `GrafanaSink` (OTLP/HTTP with gzip), `MultiSink`.\n\n---\n\nApache 2.0\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffalse-systems%2Ftapio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffalse-systems%2Ftapio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffalse-systems%2Ftapio/lists"}