Trifle::Stats
Simple analytics backed by Redis, Postgres, MongoDB, Google Analytics, Segment, or whatever. It gets you from having bunch of events occuring within few minutes to being able to say what happened on 25th January 2021.
Documentation
For comprehensive guides, API reference, and examples, visit trifle.io/trifle-stats-rb
Installation
Add this line to your application's Gemfile:
gem 'trifle-stats'And then execute:
$ bundle installOr install it yourself as:
$ gem install trifle-statsQuick Start
1. Configure
require 'trifle/stats'
Trifle::Stats.configure do |config|
config.driver = Trifle::Stats::Driver::Redis.new(Redis.new)
config.granularities = ['1m', '1h', '1d', '1w', '1mo', '1q', '1y']
end2. Track events
Trifle::Stats.track(key: 'event::logs', at: Time.now, values: { count: 1, duration: 2.11 })3. Retrieve values
Trifle::Stats.values(key: 'event::logs', from: 1.month.ago, to: Time.now, granularity: :day)
#=> {:at=>[Wed, 25 Jan 2023 00:00:00 +0000], :values=>[{"count"=>1, "duration"=>2.11}]}Drivers
Trifle::Stats supports multiple backends:
- Redis - Fast, in-memory storage
- Postgres - SQL database with JSONB support
- SQLite - SQL database in a file
- MongoDB - Document database
- Process - Thread-safe in-memory storage (development/testing)
- Dummy - No-op driver for disabled analytics
Features
- Multiple time granularities - Track data across different time periods
- Custom aggregators - Sum, average, min, max with custom logic
- Series operations - Advanced data manipulation and calculations
- Performance optimized - Efficient storage and retrieval patterns
- Buffered writes - Queue metrics locally before flushing to the driver
- Driver flexibility - Switch between storage backends easily
Buffered Persistence
Every track/assert/assort call can be buffered before touching the driver. The buffer is enabled by
default and flushes on an interval, when the queue reaches a configurable size, and again on shutdown
(SIGTERM/at_exit).
Available configuration options:
-
buffer_enabled(default:true) – Disable to write-through synchronously -
buffer_duration(default:1second) – Maximum time between automatic flushes -
buffer_size(default:256) – Maximum queued actions before forcing a flush -
buffer_aggregate(default:true) – Combine repeated operations on the same key set
Example:
Trifle::Stats.configure do |config|
config.driver = Trifle::Stats::Driver::Redis.new(Redis.new)
config.buffer_duration = 5 # flush every ~5 seconds
config.buffer_size = 100 # ...or sooner when 100 actions are enqueued
config.buffer_aggregate = true
endIf your application manages database connections manually (e.g. ActiveRecord with a pool size of 1), increase the pool size or disable buffering to avoid starving other threads.
Testing
Tests are run against all supported drivers. To run the test suite:
$ bundle exec rspecEnsure Redis, Postgres, and MongoDB are running locally. The test suite will handle database setup automatically.
Tests are meant to be simple and isolated. Every test should be independent and able to run in any order. Tests should be self-contained and set up their own configuration. This makes it easier to debug and maintain the test suite.
Use single layer testing to focus on testing a specific class or module in isolation. Use appropriate stubbing for driver methods when testing higher-level operations.
Driver tests use real database connections for accurate behavior validation. The Process driver is preferred for in-memory testing environments.
Repeat yourself in test setup for clarity rather than complex shared setups that can hide dependencies.
For performance testing:
$ cd specs/performance
$ bundle install
$ ruby run.rb 100 '{"a":1}'Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/trifle-io/trifle-stats.
License
The gem is available as open source under the terms of the MIT License.