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.
For comprehensive guides, API reference, and examples, visit trifle.io/trifle-stats-rb
Add this line to your application's Gemfile:
gem 'trifle-stats'And then execute:
$ bundle installOr install it yourself as:
$ gem install trifle-statsrequire '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']
endTrifle::Stats.track(key: 'event::logs', at: Time.now, values: { count: 1, duration: 2.11 })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}]}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
- 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
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 synchronouslybuffer_duration(default:1second) – Maximum time between automatic flushesbuffer_size(default:256) – Maximum queued actions before forcing a flushbuffer_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.
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}'Bug reports and pull requests are welcome on GitHub at https://github.com/trifle-io/trifle-stats.
The gem is available as open source under the terms of the MIT License.