DEV Community

Virendra Jadhav
Virendra Jadhav

Posted on

Introducing app_pulse: a lightweight request signal collector for Ruby apps

I recently published my first Ruby gem, app_pulse, and I wanted to share the motivation, design decisions, and lessons learned while building it.

This is not an APM, not a dashboard, and not an optimizer.

It’s a signal collector.


Why app_pulse?

In many Ruby and Rails applications, we jump too quickly to dashboards, alerts, or optimization tools before we even understand what’s happening inside our apps.

I wanted a tool that:

  • Collects request lifecycle signals
  • Is safe in production
  • Does not depend on Rails internals
  • Stores data in simple formats
  • Lets developers decide later what to do with the data

That idea became app_pulse.


What app_pulse Does

app_pulse is a Rack-based middleware that captures basic request signals:

  • Timestamp (UTC, ISO-8601)
  • HTTP method
  • Path
  • Status code
  • Duration (ms)
  • Success / failure
  • Error message (if any)

The data is stored locally in CSV, JSON, or Text files, rotated daily.

No database.
No UI.
No advice.

Just clean signals.


What app_pulse Does NOT Do

This is important:

  • ❌ No performance recommendations
  • ❌ No dashboards
  • ❌ No automatic optimization
  • ❌ No Rails-only behavior
  • ❌ No database writes

Those concerns are intentionally left for future extensions or external tools.


Design Philosophy

A few principles guided this gem:

  • Signals > opinions
  • Rack first, Rails friendly
  • Zero configuration by default
  • Fail silently, never break the host app
  • Extensible, not monolithic

Observability tools should never affect availability.


Example Usage (Rails)

# config/application.rb
config.middleware.use AppPulse::Middleware::Request
Enter fullscreen mode Exit fullscreen mode

Optional configuration:

AppPulse.configure do |config|
  config.output_path = "log/app_pulse"
  config.output_format = :csv
  config.sampling_rate = 1.0
end

Enter fullscreen mode Exit fullscreen mode

That’s it.

Ruby & Framework Compatibility

  • Ruby 2.3+

  • Rails, Rack, Sinatra

  • No ActiveSupport dependency in core

The gem is tested with modern Ruby and older Ruby (2.3) using Rack apps.


Lessons Learned

Building and releasing this gem taught me a lot about:

  • Ruby gem packaging pitfalls

  • Load path issues

  • Semantic versioning

  • Testing across Ruby versions

  • Designing APIs that don’t lock you in early

Shipping something small and correct is much harder — and more valuable — than shipping something big and fragile.


Links

Feedback, critique, and suggestions are very welcome.

Top comments (0)