Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
174f31b2
Commit
174f31b2
authored
Mar 08, 2021
by
Quang-Minh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Publish active_record transaction event
Issue
https://gitlab.com/gitlab-org/gitlab/-/issues/323163
parent
b29b1359
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
118 additions
and
20 deletions
+118
-20
lib/gitlab/database.rb
lib/gitlab/database.rb
+10
-20
spec/lib/gitlab/database_spec.rb
spec/lib/gitlab/database_spec.rb
+108
-0
No files found.
lib/gitlab/database.rb
View file @
174f31b2
...
...
@@ -313,28 +313,18 @@ module Gitlab
ActiveRecord
::
Base
.
prepend
(
ActiveRecordBaseTransactionMetrics
)
end
# observe_transaction_duration is called from ActiveRecordBaseTransactionMetrics.transaction and used to
# record transaction durations.
def
self
.
observe_transaction_duration
(
duration_seconds
)
if
current_transaction
=
::
Gitlab
::
Metrics
::
Transaction
.
current
current_transaction
.
observe
(
:gitlab_database_transaction_seconds
,
duration_seconds
)
do
docstring
"Time spent in database transactions, in seconds"
end
end
rescue
Prometheus
::
Client
::
LabelSetValidator
::
LabelSetError
=>
err
# Ensure that errors in recording these metrics don't affect the operation of the application
Gitlab
::
AppLogger
.
error
(
"Unable to observe database transaction duration:
#{
err
}
"
)
end
# MonkeyPatch for ActiveRecord::Base for adding observability
module
ActiveRecordBaseTransactionMetrics
# A monkeypatch over ActiveRecord::Base.transaction.
# It provides observability into transactional methods.
def
transaction
(
options
=
{},
&
block
)
start_time
=
Gitlab
::
Metrics
::
System
.
monotonic_time
super
(
options
,
&
block
)
ensure
Gitlab
::
Database
.
observe_transaction_duration
(
Gitlab
::
Metrics
::
System
.
monotonic_time
-
start_time
)
extend
ActiveSupport
::
Concern
class_methods
do
# A monkeypatch over ActiveRecord::Base.transaction.
# It provides observability into transactional methods.
def
transaction
(
**
options
,
&
block
)
ActiveSupport
::
Notifications
.
instrument
(
'transaction.active_record'
,
{
connection:
connection
})
do
super
(
**
options
,
&
block
)
end
end
end
end
end
...
...
spec/lib/gitlab/database_spec.rb
View file @
174f31b2
...
...
@@ -441,4 +441,112 @@ RSpec.describe Gitlab::Database do
end
end
end
describe
'ActiveRecordBaseTransactionMetrics'
do
def
subscribe_events
events
=
[]
begin
subscriber
=
ActiveSupport
::
Notifications
.
subscribe
(
'transaction.active_record'
)
do
|
e
|
events
<<
e
end
yield
ensure
ActiveSupport
::
Notifications
.
unsubscribe
(
subscriber
)
if
subscriber
end
events
end
context
'without a tranastion block'
do
it
'does not publish a transaction event'
do
events
=
subscribe_events
do
User
.
first
end
expect
(
events
).
to
be_empty
end
end
context
'within a transaction block'
do
it
'publishes a transaction event'
do
events
=
subscribe_events
do
ActiveRecord
::
Base
.
transaction
do
User
.
first
end
end
expect
(
events
.
length
).
to
be
(
1
)
event
=
events
.
first
expect
(
event
).
not_to
be_nil
expect
(
event
.
duration
).
to
be
>
0.0
expect
(
event
.
payload
).
to
a_hash_including
(
connection:
be_a
(
ActiveRecord
::
ConnectionAdapters
::
AbstractAdapter
)
)
end
end
context
'within an empty transaction block'
do
it
'publishes a transaction event'
do
events
=
subscribe_events
do
ActiveRecord
::
Base
.
transaction
{}
end
expect
(
events
.
length
).
to
be
(
1
)
event
=
events
.
first
expect
(
event
).
not_to
be_nil
expect
(
event
.
duration
).
to
be
>
0.0
expect
(
event
.
payload
).
to
a_hash_including
(
connection:
be_a
(
ActiveRecord
::
ConnectionAdapters
::
AbstractAdapter
)
)
end
end
context
'within a nested transaction block'
do
it
'publishes multiple transaction events'
do
events
=
subscribe_events
do
ActiveRecord
::
Base
.
transaction
do
ActiveRecord
::
Base
.
transaction
do
ActiveRecord
::
Base
.
transaction
do
User
.
first
end
end
end
end
expect
(
events
.
length
).
to
be
(
3
)
events
.
each
do
|
event
|
expect
(
event
).
not_to
be_nil
expect
(
event
.
duration
).
to
be
>
0.0
expect
(
event
.
payload
).
to
a_hash_including
(
connection:
be_a
(
ActiveRecord
::
ConnectionAdapters
::
AbstractAdapter
)
)
end
end
end
context
'within a cancelled transaction block'
do
it
'publishes multiple transaction events'
do
events
=
subscribe_events
do
ActiveRecord
::
Base
.
transaction
do
User
.
first
raise
ActiveRecord
::
Rollback
end
end
expect
(
events
.
length
).
to
be
(
1
)
event
=
events
.
first
expect
(
event
).
not_to
be_nil
expect
(
event
.
duration
).
to
be
>
0.0
expect
(
event
.
payload
).
to
a_hash_including
(
connection:
be_a
(
ActiveRecord
::
ConnectionAdapters
::
AbstractAdapter
)
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment