procfs

Go library for reading Linux kernel, process, and system metrics straight from /proc and /sys.

Library
Go
vv0.22.0
882stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
86/100Excellent
Development Activity88
Maintenance84
Community84
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality88
Innovation78
Learning Curve70

procfs is a Go library maintained by the Prometheus project that provides typed access to the Linux /proc and /sys pseudo-filesystems. Instead of hand-rolling file parsing for kernel data structures, callers get a Go API — a FS type representing a mount point, with methods that read and parse files like /proc/stat, /proc/[pid]/status, or /proc/meminfo into structured Go values.

The package is organized into a root procfs package for general process and kernel data plus a wide set of sub-packages (blockdevice, btrfs, bcache, nfs, sysfs, xfs, and more) for subsystem-specific metrics that require reading from both /proc and /sys. It is the metrics-collection backbone for node_exporter and other Prometheus exporters, and is widely used anywhere a Go program needs Linux-native system introspection without shelling out to external tools.

What You Get

  • A root procfs package exposing process-level data (CPU time, memory, file descriptors, namespaces, cgroups) via a simple NewFS / Proc API
  • Dozens of subsystem sub-packages (blockdevice, btrfs, bcache, bcachefs, nfs, sysfs, xfs, iscsi, resctrlfs, selinuxfs) for specialized kernel data
  • Internal parsing helpers (internal/parsers, internal/fs) shared across all subsystem readers for consistent, low-allocation file parsing
  • A ttar-based test fixture system that snapshots real /proc and /sys file trees so tests run without needing an actual Linux kernel
  • Extensive unit test coverage matching nearly every source file, exercised against the fixture trees on every CI run

Common Use Cases

  • Building Prometheus exporters (like node_exporter) that scrape Linux kernel and process metrics
  • Writing Go monitoring or observability agents that need CPU, memory, disk I/O, or network stats without shelling out to ps/vmstat/iostat
  • Reading container/cgroup resource usage and limits from within a Go application running on Linux
  • Inspecting a specific process’s state (open files, memory maps, namespaces) for debugging or security tooling
  • Collecting block-device, filesystem (btrfs/xfs/nfs), or network stack statistics for infrastructure health checks

Under The Hood

Architecture procfs is organized as a root package plus many independent subsystem sub-packages, each following the same shape: a FS type wraps one or more mount points (via the shared internal/fs.FS helper in fs.go), and methods on that type read a specific file under /proc or /sys and parse it into a typed Go struct (e.g. proc_stat.go, meminfo.go, mountstats.go). Cross-cutting parsing logic — reading files efficiently, splitting fixed-width fields, converting strings to typed numbers — lives in internal/parsers and is reused across every subsystem file rather than duplicated per-file. This keeps the per-metric files small and focused while the shared internals absorb the fiddly parts of pseudo-filesystem parsing; the top-level doc.go shows the entire library can be used in ~10 lines (procfs.Self()p.Stat()), which is representative of the API’s flat, no-ceremony design.

Tech Stack The library targets Go 1.25 and keeps its runtime dependency footprint minimal — golang.org/x/sys and golang.org/x/sync for low-level OS and concurrency primitives, with google/go-cmp used only in tests. Build and release tooling is shared with the broader Prometheus ecosystem via Makefile.common, and CI (GitHub Actions) runs a lint job (make check_license, custom build-tag checks, golangci-lint) alongside a Linux test matrix, with fixture regeneration checked via git diff --exit-code to catch stale test data.

Code Quality Test coverage is extensive and close to 1:1 with source files (proc_stat.go / proc_stat_test.go, meminfo.go / meminfo_test.go, and so on across dozens of files), exercised against real captured /proc//sys snapshots unpacked from a ttar archive rather than mocks. .golangci.yml enables a strict linter set — errorlint, forbidigo (bans stray fmt.Print calls), gocritic with nearly all checks on, revive, testifylint, plus gofmt/goimports formatting — and CI fails the build if linting or fixture regeneration drifts. Errors are returned as sentinel errors.New values (ErrFileParse, ErrFileRead, ErrMountPoint) rather than swallowed, letting callers use errors.Is for handling.

API Design The public API favors a flat, predictable shape: construct an FS for a mount point, then call a method that returns a typed struct for that specific metric — no builder chains, no configuration objects, no interfaces to implement. Every subsystem sub-package repeats this same NewFS(...) → typed-read pattern, so familiarity with one part of the library transfers directly to the others, and the root doc.go example demonstrates the entire happy path in under 15 lines. The tradeoff, called out explicitly in the README, is API stability — the library documents itself as a work in progress whose exported surface can change in backwards-incompatible ways without notice.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search