# Instrumenting Ruby code

> 原文：[https://docs.gitlab.com/ee/development/instrumentation.html](https://docs.gitlab.com/ee/development/instrumentation.html)

*   [Instrumenting Methods](#instrumenting-methods)
    *   [Examples](#examples)
    *   [Checking Instrumented Methods](#checking-instrumented-methods)
*   [Instrumenting Ruby Blocks](#instrumenting-ruby-blocks)
*   [Tracking Custom Events](#tracking-custom-events)

# Instrumenting Ruby code[](#instrumenting-ruby-code "Permalink")

[GitLab Performance Monitoring](../administration/monitoring/performance/index.html)可以检测 Ruby 代码的方法和自定义块. 方法检测是基于块的检测的主要检测形式，仅当我们想深入到方法中特定代码区域时才使用.

如果要跟踪产品使用模式，请参考[遥测](telemetry/index.html) .

## Instrumenting Methods[](#instrumenting-methods "Permalink")

使用`Gitlab::Metrics::Instrumentation`模块可以完成检测方法. 该模块提供了几种可用于检测代码的方法：

*   `instrument_method` ：检测单个类方法.
*   `instrument_instance_method` ：检测单个实例方法.
*   `instrument_class_hierarchy` ：给定一个 Class，此方法将递归地检测所有子类（类方法和实例方法）.
*   `instrument_methods` ：检测模块的所有公共和私有类方法.
*   `instrument_instance_methods` ：检测模块的所有公共和私有实例方法.

为了消除键入完整的`Gitlab::Metrics::Instrumentation`命名空间的需要，您可以使用`configure`类方法. 通过传递`Gitlab::Metrics::Instrumentation`作为其参数时，此方法仅产生提供的块. 一个例子：

```
Gitlab::Metrics::Instrumentation.configure do |conf|
  conf.instrument_method(Foo, :bar)
  conf.instrument_method(Foo, :baz)
end 
```

通常，使用此方法优于直接调用各种检测方法.

方法检测应添加到初始化程序`config/initializers/zz_metrics.rb` .

### Examples[](#examples "Permalink")

检测单个方法：

```
Gitlab::Metrics::Instrumentation.configure do |conf|
  conf.instrument_method(User, :find_by)
end 
```

检测整个类的层次结构：

```
Gitlab::Metrics::Instrumentation.configure do |conf|
  conf.instrument_class_hierarchy(ActiveRecord::Base)
end 
```

检测所有公共类方法：

```
Gitlab::Metrics::Instrumentation.configure do |conf|
  conf.instrument_methods(User)
end 
```

### Checking Instrumented Methods[](#checking-instrumented-methods "Permalink")

检查一种方法是否已被检测的最简单方法是检查其源位置. 例如：

```
method = Banzai::Renderer.method(:render)

method.source_location 
```

如果源位置指向`lib/gitlab/metrics/instrumentation.rb` ，则说明该方法已经过检测.

如果使用的是 Pry，则可以使用`$`命令显示方法的源代码（及其源位置），这比运行上面的 Ruby 代码容易. 如果是上述片段，请运行以下代码：

*   `$ Banzai::Renderer.render`

这将打印出以下内容：

```
From: /path/to/your/gitlab/lib/gitlab/metrics/instrumentation.rb @ line 148:
Owner: #<Module:0x0055f0865c6d50>
Visibility: public
Number of lines: 21

def #{name}(#{args_signature})
  if trans = Gitlab::Metrics::Instrumentation.transaction
    trans.measure_method(#{label.inspect}) { super }
  else
    super
  end
end 
```

## Instrumenting Ruby Blocks[](#instrumenting-ruby-blocks "Permalink")

通过调用`Gitlab::Metrics.measure`并将其传递给块来完成对 Ruby 代码块的测量. 例如：

```
Gitlab::Metrics.measure(:foo) do
  ...
end 
```

执行该块并将执行时间存储为当前运行的事务中的一组字段. 如果不存在事务，则不进行任何测量就产生该块.

测量一个块的三个值：

*   经过的实时时间，存储在`NAME_real_time` .
*   The CPU time elapsed, stored in `NAME_cpu_time`.
*   通话次数，存储在`NAME_call_count` .

实时和 CPU 计时均以毫秒为单位.

多次调用同一块将导致最终值是所有单个值的总和. 以下面的代码为例：

```
3.times do
  Gitlab::Metrics.measure(:sleep) do
    sleep 1
  end
end 
```

在这里， `sleep_real_time`的最终值为`3` ， *而不是* `1` .

## Tracking Custom Events[](#tracking-custom-events "Permalink")

除了检测代码，GitLab Performance Monitoring 还支持跟踪自定义事件. 这主要用于跟踪业务指标，例如 Git 推送数，存储库导入等.

要跟踪自定义事件，只需调用`Gitlab::Metrics.add_event`传递事件名称和一组自定义（可选）标签. 例如：

```
Gitlab::Metrics.add_event(:user_login, email: current_user.email) 
```

事件名称应为动词，例如`push_repository`和`remove_branch` .