low-level ruby observability apis
When we need to understand what’s going on with our application, it’s common to (beyond using puts
😉) turn to observability tools: tools such as debuggers, profilers, and monitoring tools.
But have you ever wondered how they work? These tools often require access to Ruby internals that regular Ruby libraries or applications don’t have (or need). Language runtimes such as the CRuby VM (or the Java VM!) often put in limits on what applications can do, so as to ensure the memory safety, security and integrity of applications.
To support use-cases from observability tools, the CRuby VM has a number of low-level APIs that can be used to know more about such things as the state of threads, the global VM lock, object creation, garbage collection, etc. These APIs are:
-
include/ruby/debug.h
: TracePoint, postponed job, frame-profiling, debug inspector APIs -
include/ruby/thread.h
: GVL instrumentation, thread specific storage APIs
These APIs are provided only to native extensions, and you usually need to write some C code to access them. That usually means a higher barrier of entry to start experimenting with them. And that’s not fun ;)
To fix that, I recently created (another!) Ruby gem, called lowlevel-toolkit
. The objective of this gem, as the name suggests, is to both provide a toolbox of small observability tools that probably would be too small to release independently, as well as provide a starting point and living example to quickly get started in experimenting with Ruby observability APIs.
As of this writing, the gem provides the following tools, that each make use of the APIs listed above:
-
track_wants_gvl
: Track when threads want to acquire the Global VM Lock -
track_objects_created
: Monitor object creation in your application -
last_allocation_at
: Get information about the last object allocation -
on_gc_finish
: Set up callbacks for when garbage collection finishes -
who_called_me
: Track the call stack of method invocations -
release_gvl_profiler
: Profile GVL release patterns
You can start using these tools today! Or, if you want to learn more and create your own tools, at the RubyKaigi 2025 conference I did a deep dive on each of these tools, and how the APIs they rely on work:
Slide deck:
Please do share what weird bugs you debugged and experiments you made with these APIs. I think the more people poking at these tools, the more we make it easier for everyone to understand what their Ruby apps are up to!