全部產品
Search
文件中心

Application Real-Time Monitoring Service:通過OpenTelemetry上報Ruby應用資料

更新時間:Aug 08, 2024

通過OpenTelemetry為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用OpenTelemetry為Ruby應用埋點並上報資料。

前提條件

擷取存取點資訊

  1. 登入ARMS控制台,在左側導覽列單擊接入中心

  2. 服務端應用地區單擊OpenTelemetry卡片。

  3. 在彈出的OpenTelemetry面板中選擇資料需要上報的地區。

    說明

    初次接入的地區將會自動進行資源初始化。

  4. 選擇串連方式上報方式,然後複製存取點資訊。

    • 串連方式:若您的服務部署在阿里雲上,且所屬地區與選擇的接入地區一致,推薦使用阿里雲內網方式,否則選擇公網方式。

    • 上報方式:根據用戶端支援的協議類型選擇HTTP或gRPC協議上報資料。

    image.png

背景資訊

  • Ruby版本限制:MRI Ruby ≥ 3.0,jruby ≥ 9.3.2.0,或者truffleruby ≥ 22.1。

  • OpenTelemetry Ruby支援手動埋點和半自動埋點(無需手動建立Span,但需添加一個設定檔),其中半自動埋點支援的架構請參見OpenTelemetry官方文檔

展開查看支援的Ruby架構

  • action_pack

  • action_view

  • active_job

  • active_model_serializers

  • active_record

  • active_support

  • aws_sdk

  • bunny

  • concurrent_ruby

  • dalli

  • delayed_job

  • ethon

  • excon

  • faraday

  • grape

  • graphql

  • gruf

  • http

  • http_client

  • httpx

  • koala

  • lmdb

  • mongo

  • mysql2

  • net_http

  • pg

  • que

  • racecar

  • rack

  • rails

  • rake

  • rdkafka

  • redis

  • resque

  • restclient

  • rspec

  • ruby_kafka

  • sidekiq

  • sinatra

  • trilogy

樣本Demo

範例程式碼倉庫地址:ruby-opentelemetry-demo

方法一:使用HTTP協議上報資料

  1. 安裝手動埋點所需的OpenTelemetry相關依賴。

    gem install opentelemetry-api
    gem install opentelemetry-sdk
    gem install opentelemetry-exporter-otlp
  2. OpenTelemetry初始化。

    添加匯出觀測資料的組件,將<endpoint>替換成前提條件中擷取的對應地區的Endpoint。

    require 'opentelemetry/sdk'
    require 'opentelemetry-exporter-otlp'
    
    OpenTelemetry::SDK.configure do |c|
      c.add_span_processor(
        OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
          OpenTelemetry::Exporter::OTLP::Exporter.new(
            endpoint: '<endpoint>' # HTTP方式接入
          )
        )
      )
      c.resource = OpenTelemetry::SDK::Resources::Resource.create({
        OpenTelemetry::SemanticConventions::Resource::SERVICE_NAMESPACE => 'tracing',
        OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => 'ruby_demo', # 通過OpenTelemetry上報的Ruby應用程式名稱
        OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION => '0.0.1',
      })
    end
  3. 擷取Tracer並建立新的Span。

    tracer = OpenTelemetry.tracer_provider.tracer('<your_tracer_name>', '0.1.0')
    
    tracer.in_span('parent_span') do |parent_span|
      # ...
    end
  4. 擷取當前Span,向當前Span添加資訊並擷取Trace ID和Span ID。

    # ...
    tracer.in_span('parent_span') do |parent_span|
      # current_span即parent_span
      current_span = OpenTelemetry::Trace::current_span
      current_span.set_attribute('key', 'value')
      pp current_span.context.trace_id
      pp current_span.context.span_id
    end
  5. 建立嵌套的Span。

    # ...
    tracer.in_span('parent_span') do |parent_span|
      # ...
      tracer.in_span('child_span') do |child_span|
        # 此時current_span是child_span
        current_span = OpenTelemetry::Trace::current_span
        pp current_span
      end
    end

    展開查看完整代碼

    require 'opentelemetry/sdk'
    require 'opentelemetry-exporter-otlp'
    
    OpenTelemetry::SDK.configure do |c|
      c.add_span_processor(
        OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
          OpenTelemetry::Exporter::OTLP::Exporter.new(
            endpoint: '<endpoint>' # HTTP方式接入
          )
        )
      )
      c.resource = OpenTelemetry::SDK::Resources::Resource.create({
        OpenTelemetry::SemanticConventions::Resource::SERVICE_NAMESPACE => 'tracing',
        OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => 'ruby_demo', # 通過OpenTelemetry上報的Ruby應用程式名稱
        OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION => '0.0.1',
      })
    
      # 不使用OpenTelemetry Resources API來設定應用程式名稱
      # c.service_name = 'ruby_demo'
    end
    
    tracer = OpenTelemetry.tracer_provider.tracer('instrumentation_library_name', '0.1.0')
    
    tracer.in_span('parent_span') do |parent_span|
      # 設定Attribute
      parent_span.set_attribute('language', 'ruby')
      parent_span.set_attribute("attribute_key", ["attribute_value1", "attribute_value1", "attribute_value1"])
      # 添加Event
      parent_span.add_event("event", attributes: {
        "pid" => 1234,
        "signal" => "SIGHUP"
      })
    
      # 擷取Trace ID與當前Span的Span ID
      current_span = OpenTelemetry::Trace::current_span
      pp current_span.context.trace_id
      pp current_span.context.span_id
    
      tracer.in_span('child_span') do |child_span|
        child_span.add_attributes({
          "key1" => "value1",
          "key2" => "value2"
        })
    
        child_span.add_event("mock exception here")
    
        begin
          raise 'An error has occurred'
        rescue
          # 發生異常時,將child_span的status設定為error
          child_span.status = OpenTelemetry::Trace::Status.error("error in child span")
        end
    
        pp child_span
    
      end
    end
    
    sleep 10
  6. 運行程式。

    ruby manual.rb

方法二:自動上報

OpenTelemetry Ruby也可以自動在應用程式中埋點,實現自動觀測。下面以基於Rails架構的Ruby Web應用為例,示範使用OpenTelemetry自動追蹤鏈路並上報資料。

  1. 下載開源Web應用程式框架Rails。

    gem install rails
  2. 使用Rails建立Web專案。

    rails new <your-project-name>
    • 請將<your-project-name>替換為應用程式名稱,例如:rails new auto-demo

    • 如果運行命令後出現Rails is not currently installed on this system.的報錯,請關閉終端並重新開啟,然後在新開啟的終端中重新輸入命令。

  3. 在應用目錄下的Gemfile檔案中添加以下內容。

    gem 'opentelemetry-sdk'
    gem 'opentelemetry-exporter-otlp'
    gem 'opentelemetry-instrumentation-all'
  4. 下載此Web應用所需的第三方依賴。

    1. 進入專案根目錄。

      cd <your-project-name>
    2. 下載Ruby依賴管理工具Bundler。

      gem install bundler
    3. 下載Gemfile中的依賴。

      bundle install
  5. <your-project-name>/config/initializers目錄下建立opentelemetry.rb檔案,並添加以下內容。

    # config/initializers/opentelemetry.rb
    require 'opentelemetry/sdk'
    require 'opentelemetry/exporter/otlp'
    require 'opentelemetry/instrumentation/all'
    
    OpenTelemetry::SDK.configure do |c|
      c.add_span_processor(
        OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
          OpenTelemetry::Exporter::OTLP::Exporter.new(
            endpoint: '<endpoint>' # HTTP方式接入
          )
        )
      )
      c.resource = OpenTelemetry::SDK::Resources::Resource.create({
        OpenTelemetry::SemanticConventions::Resource::HOST_NAME => '<your-host-name>', # 主機名稱
      })
      c.service_name = '<your-service-name>'    # 服務名
      c.use_all()    # 自動觀測opentelemetry支援的所有庫,
    end
    • <endpoint>替換成前提條件中擷取的對應地區的Endpoint。

    • 根據實際情況替換<your-host-name><your-service-name>

  6. 運行專案。

    rails server

    如果輸出以下內容,則表示運行成功。

    * Puma version: 5.6.5 (ruby 2.7.2-p137) ("Birdie's Version")
    *  Min threads: 5
    *  Max threads: 5
    *  Environment: development
    *          PID: 79842
    * Listening on http://127.0.0.1:3000
    * Listening on http://[::1]:3000
    Use Ctrl-C to stop
  7. 在瀏覽器中訪問http://127.0.0.1:3000,終端輸出以下內容則說明資料已上報至Managed Service for OpenTelemetry控制台。

    Started GET "/" for 127.0.0.1 at 2023-01-01 10:00:00 +0800
    Processing by Rails::WelcomeController#index as HTML
      Rendering /Users/username/.rvm/gems/ruby-2.7.2/gems/railties-7.0.4.3/lib/rails/templates/rails/welcome/index.html.erb
      Rendered /Users/username/.rvm/gems/ruby-2.7.2/gems/railties-7.0.4.3/lib/rails/templates/rails/welcome/index.html.erb (Duration: 0.8ms | Allocations: 665)
    Completed 200 OK in 6ms (Views: 2.1ms | ActiveRecord: 0.0ms | Allocations: 5440)

查看監控資料

登入ARMS控制台後,在應用監控 > 應用列表頁面選擇目標應用,查看鏈路資料。

說明

語言列顯示image表徵圖的應用為接入應用監控的應用,顯示-表徵圖的應用為接入可觀測鏈路 OpenTelemetry 版的應用。