LoginSignup
0
0

SigNozでRailsのAPMを取得&ログを無理やり転送する

Posted at

結論

  • SigNozでAPMを取得するのはわりかし簡単
  • 2024/02現在でログを転送するは若干面倒

前提条件

  • Ruby on Rails7.1の環境をDockerとdocker-compose.ymlで構築済み

手順

SigNozを構築する

を手順通りに実行

git clone -b main https://github.com/SigNoz/signoz.git && cd signoz/deploy/
docker compose -f docker/clickhouse-setup/docker-compose.yaml up -d

にアクセス

SigNozでログの転送準備

https://signoz.io/docs/userguide/send-logs-http/
の手順通りに

  • deploy/docker/clickhouse-setup/docker-compose.yamlの8082ポートを解放する
deploy/docker/clickhouse-setup/docker-compose.yaml
...
otel-collector:
    image: signoz/signoz-otel-collector:0.88.11
    command: ["--config=/etc/otel-collector-config.yaml"]
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
    ports:
      - "8082:8082" ## ここのコメントアウトを外す
...
  • deploy/docker/clickhouse-setup/otel-collector-config.yamlにhttplogreceiverを追加
deploy/docker/clickhouse-setup/otel-collector-config.yaml
receivers: 
  httplogreceiver/json: #追加
    endpoint: 0.0.0.0:8082 #追加
    source: json #追加
...

service:
    ....
    logs:
        receivers: [otlp, httplogreceiver/json]  #httplogreceiver/jsonを追加
        processors: [batch]
        exporters: [clickhouselogsexporter]
docker compose -f docker/clickhouse-setup/docker-compose.yaml up -d
もしくは
docker compose -f docker/clickhouse-setup/docker-compose.yaml restart
でSigNozを再起動する

試しにログを送ってみる

curl --location 'http://localhost:8082' \
--header 'Content-Type: application/json' \
--data '[
  {
      "trace_id": "000000000000000018c51935df0b93b9",
      "span_id": "18c51935df0b93b9",
      "trace_flags": 0,
      "severity_text": "info",
      "severity_number": 4,
      "attributes": {
          "method": "GET",
          "path": "/api/users"
      },
      "resources": {
          "host": "myhost",
          "namespace": "prod"
      },
      "message": "This is a log line"
  }
]'

This is a log line というログがSigNozで出たら成功!

Railsの設定

https://signoz.io/blog/opentelemetry-ruby/
の手順通りに

Gemfileに以下を追加して

gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
bundle install

を実行

  • config/environment.rbを編集
require 'opentelemetry/sdk'
require_relative 'application'

OpenTelemetry::SDK.configure do |c|
  c.use_all
end

Rails.application.initialize!

docker-compose.ymlを編集

docker-compose.yml
  version: "3"
  services:
    rails
.
.
.

      environment:
        OTEL_EXPORTER: otlp
        OTEL_SERVICE_NAME: sample
        OTEL_EXPORTER_OTLP_ENDPOINT: http://localhost:4318
        OTEL_EXPORTER_OTLP_ENDPOINT_LOG: http://localhost:8082

環境変数にOTEL_EXPORTER/OTEL_SERVICE_NAME/OTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_ENDPOINT_LOGを追加する

Logを転送するJobを作成する

app/jobs/send_log_data_job.rbを作成する

app/jobs/send_log_data_job.rb
class SendLogDataJob < ApplicationJob
  queue_as :default

  def perform(log_data)
    uri = URI((ENV['OTEL_EXPORTER_OTLP_ENDPOINT_LOG']).to_s)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = uri.scheme == 'https'
    request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
    request.body = log_data.is_a?(String) ? log_data : log_data.to_json
    response = http.request(request)

    Rails.logger.info "SendLogDataJob: HTTP Response Status: #{response.code}, Body: #{response.body}"
  rescue StandardError => e
    Rails.logger.error "SendLogDataJob: Failed to send log data: #{e.message}"
  end
end

app/controllers/application_controller.rbを編集しJobを呼び出す

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :capture_action_log

  private

  def capture_action_log
    start_time = Time.current
    yield
    end_time = Time.current

    trace_id = OpenTelemetry::Trace.current_span.context.hex_trace_id
    span_id = OpenTelemetry::Trace.current_span.context.hex_span_id
    duration = (end_time - start_time) * 1000.0
    body_content = {
       ## 飛ばしたいメッセージなどをテキトーに
      test: 'test',
    }

    log_data = [{
      app: ENV['OTEL_SERVICE_NAME'],
      host: request.host,
      status: response.status,
      duration:,
      trace_id:,
      span_id:,
      body: body_content.to_json
    }]

    SendLogDataJob.perform_later(log_data.to_json)
  end
end

docker-compose upなどでRailsを起動して、アプリにアクセスしてみる

すると

スクリーンショット 2024-02-10 16.04.27.png

OpenTelemetry::Instrumentation関連でめちゃくちゃログが出る
(主に警告が)

ログの中にこのようなログがでていれば、ログの転送に成功している

{"time":"2024-02-09T14:33:19.340+09:00","level":"INFO","message":"SendLogDataJob: HTTP Response Status: 200, Body: ","trace_id":"fe47f03f1b032cbb4055a94596fbef25","span_id":"995b4d6abe8cfb38","operation":"default process"}

でログを検索すると画像のようなログが見れるはず

スクリーンショット 2024-02-10 16.13.05.png

参考

https://signoz.io/docs/userguide/send-logs-http/
https://signoz.io/blog/opentelemetry-ruby/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0