Process Metrics
This project aims to collect metrics for processes.
It differs from other metric gems by measuring processes instead of code execution.
A process can begin in one point in time and finish in another thread, or even another server.
Features
- Sub-process: Start a process, track each individual step and see the global metric. This is similar to how web browsers show you in the Network view how much time each asset takes to load. See where the holes are.
- Unobtrusive: Failure in saving a metric will not break your code unless you use
Metric.measure!
,Metric#find!
andMetric#finish!
- Assyncronous: Persistence is made in parallel, so measurement itself will not affect the results.
- Multiple data stores: ActiveRecord for now. Leela2 in the near future. Implement your own if you want/need.
Usage
Manual
Single process
ProcessMetrics.measure('name') do |metric|
do_work
metric.data = { key: 'value' } # optional
end
Sub Process in the same block
ProcessMetrics.measure('name') do |metric|
metric.measure('first sub process') do |sub_metric|
do_work
sub_metric.data = { key: 'value' } # optional
end
do_more_work
metric.measure('second sub process') do |sub_metric|
do_even_more_work
sub_metric.data = { key: 'value' } # optional
end
end
Sub Processes in different places
# in app/controller/my_controller.rb
metric = ProcessMetrics.new 'name' # metric objects have an uuid
save_metric(metric.uuid)
schedule_worker
# in lib/workers/my_worker.rb
ProcessMetrics.find(metric_uuid).measure('sub process') do |sub_metric|
do_work
submetric.data = { key: 'value' } # optional
end
Automatic
Single process
class MyModel
include ProcessMetrics::Timer
measure :perform,
name: -> { "metric name" } # Default would be "MyModel#perform"
def perform
do_some_work
end
end
Sub processes
class MyWorker
include ProcessMetrics::Timer
measure :perform,
parent_metric_uuid: -> { "2d931510-d99f-494a-8c67-87feb05e1594" }
belongs_to :my_model
def perform
do_some_work
end
end
Persistence
Data collected will be serialized into a json and persisted. You can put any data you like into the data field and it will be serialized as well.
{
"metrics": [{
"uuid": "bad85eb9-0713-4da7-8d36-07a8e4b00eab",
"name": "virtual_machine_provisioning",
"started_at": "2014-03-13T11:34:53-03:00",
"finished_at": "2014-03-13T11:35:14-03:00",
"data": {
"customer_login": "anon",
"provisioning_id": 6000123456,
"object_type": "virtual_machine",
"object_id": "cpro123456"
},
"links": {
"metrics": [
"2d931510-d99f-494a-8c67-87feb05e1594",
"62936e70-1815-439b-bf89-8492855a7e6b"
]
}
}]
}
Configuration
One time, in a migration
ProcessMetrics::Persistence::ActiveRecord.table_name = 'onon' # optional
ProcessMetrics::Persistence::ActiveRecord.setup!
Then, in an initializer
ProcessMetrics.config.logger = Rails.logger
ProcessMetrics.persistence = Metric::Persistence::ActiveRecord # Default is Logger