結論
- 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ポートを解放する
...
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を追加
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を編集
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を作成する
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を呼び出す
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を起動して、アプリにアクセスしてみる
すると
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"}
でログを検索すると画像のようなログが見れるはず
参考
https://signoz.io/docs/userguide/send-logs-http/
https://signoz.io/blog/opentelemetry-ruby/