+ Use NullMetrics to mock metrics when unused
+ Use method_missing in NullMetrics mocking
+ Update prometheus gem to version that correctly uses transitive dependencies
+ Ensure correct folders are used in Multiprocess prometheus client tests.
+ rename Sessions controller's metric
On initial startup with no rows in the application_settings table, the
metaprogramming call to `if enabled?` attempts to create a row. This triggers
the HTML caching path, which attempts to store metrics.
At this point, not all the methods in `Gitlab::Metrics` have been defined! Move
`current_transaction` to be defined before running the metaprogramming, to
avoid a confusing NoMethodError
GitLab Performance Monitoring is now able to track custom events not
directly related to application performance. These events include the
number of tags pushed, repositories created, builds registered, etc.
The use of these events is to get a better overview of how a GitLab
instance is used and how that may affect performance. For example, a
large number of Git pushes may have a negative impact on the underlying
storage engine.
Events are stored in the "events" measurement and are not prefixed with
"rails_" or "sidekiq_", this makes it easier to query events with the
same name triggered from different parts of the application. All events
being stored in the same measurement also makes it easier to downsample
data.
Currently the following events are tracked:
* Creating repositories
* Removing repositories
* Changing the default branch of a repository
* Pushing a new tag
* Removing an existing tag
* Pushing a commit (along with the branch being pushed to)
* Pushing a new branch
* Removing an existing branch
* Importing a repository (along with the URL we're importing)
* Forking a repository (along with the source/target path)
* CI builds registered (and when no build could be found)
* CI builds being updated
* Rails and Sidekiq exceptions
Fixesgitlab-org/gitlab-ce#13720
Enable Rubocop cops that check access modifiers
## What does this MR do?
This MR enables Rubocop cops that detect methods that should be restricted but are the part of public API because of access modifiers used improperly.
This also fixes existing offenses.
## Why was this MR needed?
Some method in our codebase are public instead of being private because it is sometimes difficult to get it right without static analysis.
## What are the relevant issue numbers?
See #17478Closes#17372
See merge request !5014
This reduces the overhead of the method instrumentation code primarily
by reducing the number of method calls. There are also some other small
optimisations such as not casting timing values to Floats (there's no
particular need for this), using Symbols for method call metric names,
and reducing the number of Hash lookups for instrumented methods.
The exact impact depends on the code being executed. For example, for a
method that's only called once the difference won't be very noticeable.
However, for methods that are called many times the difference can be
more significant.
For example, the loading time of a large commit
(nrclark/dummy_project@81ebdea5df)
was reduced from around 19 seconds to around 15 seconds using these
changes.
Merely setting the "action" tag will only result in the transaction
itself containing a value for this tag. To ensure other metrics also
contain this tag we must set the action using Transaction#action=
instead.
This allows users to configure the number of points stored in a single
UDP packet. This in turn can be used to reduce the number of UDP packets
being sent at the cost of these packets being somewhat larger.
The default setting is 1 point per packet so nothing changes for
existing users.
One use case for this is manually setting the "action" tag for Grape API
calls. Due to Grape running blocks there are no human readable method
names that can be used for the "action" tag, thus we have to set these
manually on a case by case basis.
If the measure method uses Transaction.current directly the SQL
subscriber (Subscribers::ActiveRecord) will add timings of queries
triggered by DB cleaner.
This makes it easier to query, simplifies the code, and makes it
possible to figure out what transaction the data belongs to (simply
because it's now stored _in_ the transaction).
This new setup keeps track of both the real/wall time _and_ CPU time
spent in a block, both measured using milliseconds (to keep all units
the same).
This allows measuring of timings of arbitrary Ruby blocks, this allows
for more fine grained performance monitoring. Custom values and tags can
also be attached to a block.
Where a vew is called from doesn't matter as much. We already know what
action they belong to and this is more than enough information. By
removing the file/line number from the list of tags we should also be
able to reduce the number of series stored in InfluxDB.
This removes the need for Sidekiq and any overhead/problems introduced
by TCP. There are a few things to take into account:
1. When writing data to InfluxDB you may still get an error if the
server becomes unavailable during the write. Because of this we're
catching all exceptions and just ignore them (for now).
2. Writing via UDP apparently requires the timestamp to be in
nanoseconds. Without this data either isn't written properly.
3. Due to the restrictions on UDP buffer sizes we're writing metrics one
by one, instead of writing all of them at once.
This ensures we don't end up wasting resources by tracking method calls
that only take a few microseconds. By default the threshold is 10
milliseconds but this can be changed using the gitlab.yml configuration
file.
The previous setup wasn't exactly fast, resulting in instrumented method
calls taking about 600 times longer than non instrumented calls
(including any ActiveSupport code involved). With this commit this
slowdown has been reduced to around 185 times.