{"id":22390485,"url":"https://github.com/maxgio92/yet-another-profiler","last_synced_at":"2025-07-31T07:33:00.361Z","repository":{"id":230088559,"uuid":"639489477","full_name":"maxgio92/yet-another-profiler","owner":"maxgio92","description":"Yet Another low-overhead kernel-assisted sampling-based CPU time continuous Profiler.","archived":false,"fork":false,"pushed_at":"2024-11-29T15:15:05.000Z","size":735,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-29T16:20:14.968Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxgio92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-05-11T14:56:07.000Z","updated_at":"2024-11-29T15:03:42.000Z","dependencies_parsed_at":"2024-04-24T19:29:24.149Z","dependency_job_id":"d06ed232-394a-4af7-9201-8d7edb43ec24","html_url":"https://github.com/maxgio92/yet-another-profiler","commit_stats":null,"previous_names":["maxgio92/cpu-profiler","maxgio92/yap","maxgio92/yet-another-profiler"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxgio92%2Fyet-another-profiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxgio92%2Fyet-another-profiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxgio92%2Fyet-another-profiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxgio92%2Fyet-another-profiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxgio92","download_url":"https://codeload.github.com/maxgio92/yet-another-profiler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228224637,"owners_count":17887844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-12-05T03:16:58.139Z","updated_at":"2025-07-31T07:33:00.345Z","avatar_url":"https://github.com/maxgio92.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Yap\n\nYet Another Profiler written in Go and eBPF\n\n\u003e This is an experimental project. Use at your own risk.\n\nThis is a low-overhead kernel-assisted sampling-based CPU time continuous profile. It does not need instrumentation in the profiled binary.\n\nA simple sampling eBPF program attached to a timer collects:\n- stack traces\n- sampled stack trace counts\n\nThe data collected from the kernel is analysed in user-space to summarise residency fraction.\nThat is, for a stack trace, the percentage of samples that contained that path out of the total amount of samples.\n\nThis information extracted from the collected data expresses, for a specific process, which functions are mostly executing.\n\n## How it works\n\nThe sampling eBPF probe is attached to a perf [CPU clock software event](https://elixir.bootlin.com/linux/v6.8.5/source/include/uapi/linux/perf_event.h#L119).\n\nThe user and kernel stack traces that are running on the current CPU are available to the eBPF program that will run in the context of the interrupted process via the [`bpf_get_stackid`](https://elixir.bootlin.com/linux/v6.8.5/source/kernel/bpf/stackmap.c#L283) eBPF helper.\nThe user or kernel stack will be available depending on the context during which the process was interrupted.\n\nThe hard work of stack walking is made easy by the Linux kernel thanks to the fact that frame instruction pointers of the sampled stack traces are available in kernel space via the [`BPF_MAP_TYPE_STACK_TRACE`](https://elixir.bootlin.com/linux/v6.8.5/source/include/uapi/linux/bpf.h#L914) eBPF map.\n\nThe information about how much a specific stack has been sampled is tracked with counters stored in an histogram eBPF map, which is keyed by:\n- User stack ID\n- Kernel stack ID\n- PID to filter later on\n\nand made available to userspace, alongside the stack traces.\n\nIn userspace symbolization is made with frame instruction pointer addresses and the ELF symbol table.\n\nFinally, the information is extracted as percentage of profile time a stack trace has been executing.\n\n## Current limitations\n\nDue to the current implementation there are some limitations on the supported binaries to make CPU profiling properly work and finally provide a meaningful report:\n* because it leverages frame pointers for stack unwinding, binaries compiled without frame pointers are not currently supported.\n* because it leverages the ELF symbol table (`.symtab` section) for the symbolization, stripped binaries are not supported in the current version. By the way, debug symbol are not required to be included in the final binary to make symbolization properly work.\n\n## Quickstart\n\n## Usage\n\n```\nyap profile [--debug] --pid PID\nOptions:\n  -debug\n      Sets log level to debug\n  -pid int\n      The PID of the process\n```\n\nFor a detailed reference please refer to the [CLI reference](./docs) documentation.\n\n### Example\n\nConsidering a go program made it running in background:\n\n```shell\ngo build -v -o myprogram\n./myprogram \u0026\n[1] 95541\n```\n\nLet's profile it:\n\n```shell\nsudo yap profile --pid 95541\n{\"level\":\"info\",\"message\":\"collecting data\"}\n^C{\"level\":\"info\",\"message\":\"terminating...\"}\nResidency Stack trace\n 2.6%     main.main;runtime.main;runtime.goexit.abi0;\n65.3%     main.foo;runtime.main;runtime.goexit.abi0;\n32.1%     main.bar;runtime.main;runtime.goexit.abi0;\n```\n\n### Graphviz support\n\n`yap` can generate a DOT graph to be rendered by specifying the `--output=dot` to the `profile` command.\n\nConsidering a profile similar to the one from the example above, a DAG would be generated like below:\n\n![Profile DAG](./docs/profile-dag.dot.svg)\n\n## Build\n\n### Prerequisites\n\n* clang\n* libbpf-dev\n* libelf (optional: required to build bpftool)\n* zlib (optional: required by bpftool)\n\n### Build all\n\n```shell\nmake yap\n```\n\n### eBPF probe only\n\n```shell\nmake yap/bpf\n```\n\n## Credits\n\n- Pixie:\n  - [pixie-demos/ebpf-profiler](https://github.com/pixie-io/pixie-demos/tree/main/ebpf-profiler)\n  - [Building a continuous profiler](https://blog.px.dev/cpu-profiling/)\n- Linux:\n  - [samples/bpf/trace_event_user.c](https://github.com/torvalds/linux/blob/8f2c057754b25075aa3da132cd4fd4478cdab854/samples/bpf/trace_event_user.c)\n  - [samples/bpf/trace_event_kern.c](https://github.com/torvalds/linux/blob/8f2c057754b25075aa3da132cd4fd4478cdab854/samples/bpf/trace_event_kern.c)\n- Brendan Gregg:\n  - [Linux eBPF Stack Trace Hack](https://www.brendangregg.com/blog/2016-01-18/ebpf-stack-trace-hack.html)\n- Aqua Security\n  - [Tracee](https://github.com/aquasecurity/tracee)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxgio92%2Fyet-another-profiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxgio92%2Fyet-another-profiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxgio92%2Fyet-another-profiler/lists"}