Commit 5679ee01 authored by Yorick Peterse's avatar Yorick Peterse

Track memory allocated during a transaction

This gives a very rough estimate of how much memory is allocated during
a transaction. This only works reliably when using a single-threaded
application server and a Ruby implementation with a GIL as otherwise
memory allocated by other threads might skew the statistics. Sadly
there's no way around this as Ruby doesn't provide a reliable way of
gathering accurate object sizes upon allocation on a per-thread basis.
parent 587f8501
...@@ -23,20 +23,29 @@ module Gitlab ...@@ -23,20 +23,29 @@ module Gitlab
@values = Hash.new(0) @values = Hash.new(0)
@tags = {} @tags = {}
@action = action @action = action
@memory_before = 0
@memory_after = 0
end end
def duration def duration
@finished_at ? (@finished_at - @started_at) * 1000.0 : 0.0 @finished_at ? (@finished_at - @started_at) * 1000.0 : 0.0
end end
def allocated_memory
@memory_after - @memory_before
end
def run def run
Thread.current[THREAD_KEY] = self Thread.current[THREAD_KEY] = self
@started_at = Time.now @memory_before = System.memory_usage
@started_at = Time.now
yield yield
ensure ensure
@finished_at = Time.now @memory_after = System.memory_usage
@finished_at = Time.now
Thread.current[THREAD_KEY] = nil Thread.current[THREAD_KEY] = nil
end end
...@@ -65,7 +74,7 @@ module Gitlab ...@@ -65,7 +74,7 @@ module Gitlab
end end
def track_self def track_self
values = { duration: duration } values = { duration: duration, allocated_memory: allocated_memory }
@values.each do |name, value| @values.each do |name, value|
values[name] = value values[name] = value
......
...@@ -11,6 +11,14 @@ describe Gitlab::Metrics::Transaction do ...@@ -11,6 +11,14 @@ describe Gitlab::Metrics::Transaction do
end end
end end
describe '#allocated_memory' do
it 'returns the allocated memory in bytes' do
transaction.run { 'a' * 32 }
expect(transaction.allocated_memory).to be_a_kind_of(Numeric)
end
end
describe '#run' do describe '#run' do
it 'yields the supplied block' do it 'yields the supplied block' do
expect { |b| transaction.run(&b) }.to yield_control expect { |b| transaction.run(&b) }.to yield_control
...@@ -43,8 +51,10 @@ describe Gitlab::Metrics::Transaction do ...@@ -43,8 +51,10 @@ describe Gitlab::Metrics::Transaction do
transaction.increment(:time, 1) transaction.increment(:time, 1)
transaction.increment(:time, 2) transaction.increment(:time, 2)
values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) }
expect(transaction).to receive(:add_metric). expect(transaction).to receive(:add_metric).
with('transactions', { duration: 0.0, time: 3 }, {}) with('transactions', values, {})
transaction.track_self transaction.track_self
end end
...@@ -54,8 +64,14 @@ describe Gitlab::Metrics::Transaction do ...@@ -54,8 +64,14 @@ describe Gitlab::Metrics::Transaction do
it 'sets a value' do it 'sets a value' do
transaction.set(:number, 10) transaction.set(:number, 10)
values = {
duration: 0.0,
number: 10,
allocated_memory: a_kind_of(Numeric)
}
expect(transaction).to receive(:add_metric). expect(transaction).to receive(:add_metric).
with('transactions', { duration: 0.0, number: 10 }, {}) with('transactions', values, {})
transaction.track_self transaction.track_self
end end
...@@ -80,8 +96,13 @@ describe Gitlab::Metrics::Transaction do ...@@ -80,8 +96,13 @@ describe Gitlab::Metrics::Transaction do
describe '#track_self' do describe '#track_self' do
it 'adds a metric for the transaction itself' do it 'adds a metric for the transaction itself' do
values = {
duration: transaction.duration,
allocated_memory: a_kind_of(Numeric)
}
expect(transaction).to receive(:add_metric). expect(transaction).to receive(:add_metric).
with('transactions', { duration: transaction.duration }, {}) with('transactions', values, {})
transaction.track_self transaction.track_self
end end
...@@ -104,7 +125,7 @@ describe Gitlab::Metrics::Transaction do ...@@ -104,7 +125,7 @@ describe Gitlab::Metrics::Transaction do
hash = { hash = {
series: 'rails_transactions', series: 'rails_transactions',
tags: { action: 'Foo#bar' }, tags: { action: 'Foo#bar' },
values: { duration: 0.0 }, values: { duration: 0.0, allocated_memory: a_kind_of(Numeric) },
timestamp: an_instance_of(Fixnum) timestamp: an_instance_of(Fixnum)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment