summaryrefslogtreecommitdiff
path: root/lib/gitlab/metrics
Commit message (Collapse)AuthorAgeFilesLines
* Use Grape's new Route methods25908-fix-grape-after-updateRémy Coutable2016-12-211-2/+2
| | | | | | | - Use Route#request_method instead of Route#route_method - Use Route#path instead of Route#route_path Signed-off-by: Rémy Coutable <remy@rymai.me>
* Adds response mime type to transaction metric action when it's not HTMLPaco Guzman2016-08-251-2/+20
|
* Tracking of custom eventscustom-events-trackingYorick Peterse2016-08-174-4/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 Fixes gitlab-org/gitlab-ce#13720
* Reduce instrumentation overheadYorick Peterse2016-07-284-32/+20
| | | | | | | | | | | | | | | | | | 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@81ebdea5df2fb42e59257cb3eaad671a5c53ca36) was reduced from around 19 seconds to around 15 seconds using these changes.
* RailsCache metrics now includes fetch_hit/fetch_miss and read_hit/read_miss ↵Paco Guzman2016-07-051-2/+12
| | | | info.
* Instrument cache fetch hit and cache fetch missesPaco Guzman2016-07-051-0/+12
|
* Use clock_gettime for all performance timestampsperformance-clock-adjustmentsYorick Peterse2016-06-284-19/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Process.clock_gettime allows getting the real time in nanoseconds as well as allowing one to get a monotonic timestamp. This offers greater accuracy without the overhead of having to allocate a Time instance. In general using Time.now/Time.new is about 2x slower than using Process.clock_gettime(). For example: require 'benchmark/ips' Benchmark.ips do |bench| bench.report 'Time.now' do Time.now.to_f end bench.report 'clock_gettime' do Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) end bench.compare! end Running this benchmark gives: Calculating ------------------------------------- Time.now 108.052k i/100ms clock_gettime 125.984k i/100ms ------------------------------------------------- Time.now 2.343M (± 7.1%) i/s - 11.670M clock_gettime 4.979M (± 0.8%) i/s - 24.945M Comparison: clock_gettime: 4979393.8 i/s Time.now: 2342986.8 i/s - 2.13x slower Another benefit of using Process.clock_gettime() is that we can simplify the code a bit since it can give timestamps in nanoseconds out of the box.
* Add Sidekiq queue duration to transaction metrics.Paco Guzman2016-06-231-0/+2
|
* Track method call times/counts as a single metricYorick Peterse2016-06-173-22/+84
| | | | | | | | | | | | | | | | Previously we'd create a separate Metric instance for every method call that would exceed the method call threshold. This is problematic because it doesn't provide us with information to accurately get the _total_ execution time of a particular method. For example, if the method "Foo#bar" was called 4 times with a runtime of ~10 milliseconds we'd end up with 4 different Metric instances. If we were to then get the average/95th percentile/etc of the timings this would be roughly 10 milliseconds. However, the _actual_ total time spent in this method would be around 40 milliseconds. To solve this problem we now create a single Metric instance per method. This Metric instance contains the _total_ real/CPU time and the call count for every instrumented method.
* Filter out sensitive parameters of metrics dataPaco Guzman2016-06-171-1/+5
|
* Filter out classes without names in the samplerYorick Peterse2016-06-141-1/+5
| | | | | | We can't do a lot with classes without names as we can't filter by them, have no idea where they come from, etc. As such it's best to just ignore these.
* Merge branch '18449-instrument-grape-endpoints' into 'master' Yorick Peterse2016-06-141-1/+24
|\ | | | | | | | | Instrument Grape API endpoints See merge request !4587
| * Instrument Grape Endpoint with Metrics::RackMiddleware18449-instrument-grape-endpointsPaco Guzman2016-06-141-1/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Generating the following tags Grape#GET /projects/:id/archive from Grape::Route objects like { :path => /:version/projects/:id/archive(.:format) :version => “v3”, :method => “GET” } Use an instance variable to cache raw_path transformations. This variable is only going to growth to the number of endpoints of the API, not with exact different requests We can store this cache as an instance variable because middleware are initialised only once
* | Instrument private/protected methodsPaco Guzman2016-06-141-4/+6
| | | | | | | | | | | | | | By default instrumentation will instrument public, protected and private methods, because usually heavy work is done on private method or at least that’s what facts is showing
* | Measure CPU time for instrumented methodsPaco Guzman2016-06-141-4/+7
|/
* Add cache count metrics to rails cacheadd-cache-count-metricsPablo Carranza2016-05-151-5/+7
|
* Removed tracking of total method execution timestotal-method-timeYorick Peterse2016-05-121-2/+0
| | | | | | | | | | | Because method call timings are inclusive (that is, they include the time of any sub method calls) this would lead to the total method execution time often being far greater than the total transaction time. Because this is incredibly confusing it's best to simply _not_ track the total method execution time, after all it's not that useful to begin with. Fixes gitlab-org/gitlab-ce#17239
* Count the number of SQL queries per transactionYorick Peterse2016-04-181-0/+1
| | | | Fixes gitlab-org/gitlab-ce#15335
* Use Module#prepend for method instrumentationfix-method-instrumentationYorick Peterse2016-04-181-10/+27
| | | | | | | | | By using Module#prepend we can define a Module containing all proxy methods. This removes the need for setting up crazy method alias chains and in turn prevents us from having to deal with all that madness (e.g. methods calling each other recursively). Fixes gitlab-org/gitlab-ce#15281
* Store block timings as transaction valuesYorick Peterse2016-04-111-0/+11
| | | | | | | | | | 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).
* Merge branch 'instrument-rails-cache' into 'master' Yorick Peterse2016-04-081-0/+39
|\ | | | | | | | | Instrument Rails cache code See merge request !3619
| * Instrument Rails cache codeinstrument-rails-cacheYorick Peterse2016-04-081-0/+39
| | | | | | | | | | This allows us to track how much time of a transaction is spent in dealing with cached data.
* | Use more accurate timestamps for InfluxDB.metrics-timestamp-precisionYorick Peterse2016-04-081-1/+21
|/ | | | | | | | | This changes the timestamp of metrics to be more accurate/unique by using Time#to_f combined with a small random jitter value. This combination hopefully reduces the amount of collisions, though there's no way to fully prevent any from occurring. Fixes gitlab-com/operations#175
* Correct arity for instrumented methods w/o argsinstrumentation-signatureYorick Peterse2016-01-251-3/+19
| | | | | | | | | | | | This ensures that an instrumented method that doesn't take arguments reports an arity of 0, instead of -1. If Ruby had a proper method for finding out the required arguments of a method (e.g. Method#required_arguments) this would not have been an issue. Sadly the only two methods we have are Method#parameters and Method#arity, and both are equally painful to use. Fixes gitlab-org/gitlab-ce#12450
* Randomize metrics sample intervalsconfigure-randomize-metrics-sample-intervalYorick Peterse2016-01-131-3/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Sampling data at a fixed interval means we can potentially miss data from events occurring between sampling intervals. For example, say we sample data every 15 seconds but Unicorn workers get killed after 10 seconds. In this particular case it's possible to miss interesting data as the sampler will never get to actually submitting data. To work around this (at least for the most part) the sampling interval is randomized as following: 1. Take the user specified sampling interval (15 seconds by default) 2. Divide it by 2 (referred to as "half" below) 3. Generate a range (using a step of 0.1) from -"half" to "half" 4. Every time the sampler goes to sleep we'll grab the user provided interval and add a randomly chosen "adjustment" to it while making sure we don't pick the same value twice in a row. For a specified timeout of 15 this means the actual intervals can be anywhere between 7.5 and 22.5, but never can the same interval be used twice in a row. The rationale behind this change is that on dev.gitlab.org I'm sometimes seeing certain Gitlab::Git/Rugged objects being retained, but only for a few minutes every 24 hours. Knowing the code of Gitlab and how much memory it uses/leaks I suspect we're missing data due to workers getting terminated before the sampler can write its data to InfluxDB.
* Make the metrics sampler interval configurableYorick Peterse2016-01-131-1/+1
|
* Merge branch 'remove-application-frames-from-views' into 'master' Yorick Peterse2016-01-121-9/+1
|\ | | | | See merge request !2392
| * Stop tracking call stacks for instrumented viewsremove-application-frames-from-viewsYorick Peterse2016-01-121-9/+1
| | | | | | | | | | | | | | 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.
* | Track memory allocated during a transactionYorick Peterse2016-01-121-3/+12
|/ | | | | | | | | 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.
* Tag all transaction metrics with an "action" tagYorick Peterse2016-01-113-12/+18
| | | | | | | Without this it's impossible to find out what methods/views/queries are executed by a certain controller or Sidekiq worker. While this will increase the total number of series it should stay within reasonable limits due to the amount of "actions" being small enough.
* Store request methods/URIs as valuesYorick Peterse2016-01-072-3/+7
| | | | | | | Since filtering by these values is very rare (they're mostly just displayed as-is) we don't need to waste any index space by saving them as tags. By storing them as values we also greatly reduce the number of series in InfluxDB.
* Removed UUIDs from metrics transactionsYorick Peterse2016-01-071-3/+1
| | | | | While useful for finding out what methods/views belong to a transaction this might result in too much data being stored in InfluxDB.
* Revert "Store SQL/view timings in milliseconds"Yorick Peterse2016-01-072-11/+3
| | | | | | | | This reverts commit 7549102bb727daecc51da84af39956b32fc41537. Apparently I was wrong about ActiveSupport::Notifications::Event#duration returning the duration in seconds, instead it returns it in milliseconds already.
* Store SQL/view timings in millisecondsYorick Peterse2016-01-062-3/+11
| | | | | Transaction timings are also already stored in milliseconds, this keeps things consistent.
* Automatically prefix transaction series namesYorick Peterse2016-01-043-12/+11
| | | | | This ensures Rails and Sidekiq transactions are split into the series "rails_transactions" and "sidekiq_transactions" respectively.
* Use separate series for Rails/Sidekiq sample statsYorick Peterse2016-01-041-5/+14
| | | | | This removes the need for any tags to differentiate between Sidekiq and Rails statistics while still being able to separate the two.
* Track total method call times per transactionYorick Peterse2016-01-041-0/+2
| | | | | This makes it easier to see where time is spent without having to aggregate all the individual points in the method_calls series.
* Track total query/view timings in transactionsYorick Peterse2016-01-042-0/+23
|
* Ability to increment custom transaction valuesYorick Peterse2016-01-041-2/+13
| | | | | | This will be used to store/increment the total query/view rendering timings on a per transaction basis. This in turn can greatly reduce the amount of metrics stored.
* Removed tracking of hostnames for metricsYorick Peterse2015-12-311-4/+2
| | | | | This isn't hugely useful and mostly wastes InfluxDB space. We can re-add this whenever needed (but only once we really need it).
* Use separate series for Rails/Sidekiq transactionsYorick Peterse2015-12-314-8/+10
| | | | This removes the need for tagging all metrics with a "process_type" tag.
* Removed tracking of raw SQL queriesYorick Peterse2015-12-312-95/+0
| | | | | | | | | | | | This particular setup had 3 problems: 1. Storing SQL queries as tags is very inefficient as InfluxDB ends up indexing every query (and they can get pretty large). Storing these as values instead means we can't always display the SQL as easily. 2. We already instrument ActiveRecord query methods, thus we already have timing information about database queries. 3. SQL obfuscation is difficult to get right and I'd rather not expose sensitive data by accident.
* Removed various default metrics tagsreduce-influxdb-tagsYorick Peterse2015-12-311-5/+2
| | | | | | | | While it's useful to keep track of the different versions (Ruby, GitLab, etc) doing so for every point wastes disk space and possibly also RAM (which InfluxDB is all to eager to gobble up). If we want to see the performance differences between different GitLab versions simply looking at the performance since the last release date should suffice.
* Write to InfluxDB directly via UDPYorick Peterse2015-12-295-11/+4
| | | | | | | | | | | | | 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.
* Strip newlines from obfuscated SQLYorick Peterse2015-12-291-1/+1
| | | | | Newlines aren't really needed and they may mess with InfluxDB's line protocol.
* Use String#delete for removing double quotesYorick Peterse2015-12-281-1/+1
|
* Track object counts using the "allocations" GemYorick Peterse2015-12-171-3/+22
| | | | | This allows us to track the counts of actual classes instead of "T_XXX" nodes. This is only enabled on CRuby as it uses CRuby specific APIs.
* Support for instrumenting class hierarchiesYorick Peterse2015-12-171-0/+23
| | | | This will be used to (for example) instrument all ActiveRecord models.
* Only track method calls above a certain thresholdYorick Peterse2015-12-171-3/+5
| | | | | | | 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.
* Allow filtering of what methods to instrumentYorick Peterse2015-12-171-2/+17
| | | | | This makes it possible to determine if a method should be instrumented or not using a block.