์ด ๋ฌธ์์์๋ ๋ฃจ๋น ์์ด์ ํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ gem์ ๋๋ฒ๊ทธํ๋ ๋ฐฉ๋ฒ๊ณผ ์์ด์ ํธ์ ์ํธ ์์ฉํ๊ธฐ ์ํ ์ผ๋ถ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์์ธํ ์ค๋ช
ํฉ๋๋ค. ์ด๋ Ruby ์์ด์ ํธ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฆฌ์์ค๋ฅผ ์ถ์ํ์ง ์๋ gem์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋ฆฌ์์ค๋ฅผ ์ถ๊ฐํ๋ ค๋ gem ์์ฑ์์ธ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
ํ์ฌ ํ์ฅ ์ฐพ๊ธฐ
๋๊ตฌ๋ Ruby ์์ด์ ํธ ์์ ๋น๋๋๋ gem์ ์์ฑํ ์ ์์ต๋๋ค. ๋ด๋ ๋ฆญ์ ์ด๋ฌํ ํ์ฅ์ ์ถ์ ํ๊ณ Ruby ์์ด์ ํธ๋ฅผ ๊ตฌ์ถํ๋ ๋ค๋ฅธ gem์ ๋ํ ๋งํฌ๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด extends_newrelic_rpm ์ด๋ผ๋ ํด๋ฌ์คํฐ๋ฅผ ์ ์ง ๊ด๋ฆฌํฉ๋๋ค.
์ด๋ฌํ ํ์ฅ์ New Relic์์ ์ง์ ๋์ง ์์ต๋๋ค . New Relic์ ์ด๋ฌํ ๋งํฌ๋ฅผ ๊ณ ๊ฐ์ ๋ํ ์๋น์ค๋ก ์์งํฉ๋๋ค. ์ด๋ฌํ gem๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ GitHub์ ํด๋น ํ๋ก์ ํธ์ ๋ณด๊ณ ํด์ผ ํฉ๋๋ค.
๋ณด์์ผ๋ก์์ ํ์ฅ
New Relic์ ๊ณ์ธก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋น ํ๋์ gem์ผ๋ก ํ์ฌ ํ์ฅ์ gem์ผ๋ก ์ ์งํ๋๋ก ๊ถ์ฅํฉ๋๋ค. ์๋ฅผ ๋ค์ด, newrelic-redis ์ redis gem์ ๋ํ ๊ณ์ธก์ ์ ๊ณตํฉ๋๋ค.
๊ฑฐ๋ ์์
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ New Relic์์ ์ ์ฒด ํธ๋์ญ์
์ผ๋ก ํ์๋์ด์ผ ํ๋ ์ฝ๋๋ฅผ ์ ๊ณตํ๋ ๊ฒฝ์ฐ(์: Ruby ์์ด์ ํธ์ ์ํด ๊ณ์ธก๋์ง ์๋ ์น ์์ฒญ ๋๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
) ํธ๋์ญ์
์ ์์ํ๊ธฐ ์ํด ์ด๋ฌํ ๋ฉ์ปค๋์ฆ ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ญ์์ค.
ํธ๋์ญ์
์ ์์ํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๋ฉ์๋์์ add_transaction_tracer ๋ฅผ ํธ์ถํ๋ ๊ฒ์
๋๋ค. ์ด๊ฒ์ NewRelic::Agent::Instrumentation::ControllerInstrumentation ์ด(๊ฐ) ํด๋์ค์ ํฌํจ๋์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
class CustomBackgroundJob
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
add_transaction_tracer :transaction
๋๋๋ก New Relic์ด ์์ฑํ๋ ํธ๋์ญ์
์ ์ฝ๊ฐ ๋ ์ ์ดํด์ผ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ perform_action_with_newrelic_trace ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ์ ์ํ ์ ์๋ ์ผ๋ถ ๋งค๊ฐ๋ณ์์๋ ํธ๋์ญ์
์ด๋ฆ ๋ฐ ๋ฒ์ฃผ(์น ํธ๋์ญ์
์ด๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํธ๋์ญ์
์ด๋ )๊ฐ ํฌํจ๋ฉ๋๋ค.
class CustomBackgroundJob
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
perform_action_with_newrelic_trace(:name => "custom_name",
์์ธํ ํ๋ผ๋ฏธํฐ, ๋ณ์ ๋ฐ ์ฌ์ฉ๋ฒ์ perform_action_with_newrelic_trace์ ์ ์ฒด ์ค๋ช
์๋ฅผ ์ฐธ์กฐํ์ธ์.
ํธ๋์ญ์
์ถ์ ์ ๋
ธ๋
๋ฉ์๋ ํธ์ถ์ ๋ํ ํ์ด๋ฐ ์ ๋ณด๋ฅผ New Relic์ ์ถ๊ฐํ ์ ์์ง๋ง ์ ์ฒด ํธ๋์ญ์
์ ๋ํ๋ด์ง๋ ์์ต๋๋ค. New Relic์ ์ด๋ฅผ ์ํํ๊ธฐ ์ํด ๋ฉ์๋ ์ถ์ ํ๋ก๊ทธ๋จ์ ์ถ๊ฐํ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
require 'new_relic/agent/method_tracer'
include ::NewRelic::Agent::MethodTracer
add_method_tracer :generate_image, 'Custom/generate_image'
์์ ์์์๋ 'Custom/generate_image' ์ด๋ฆ์ ๋ํ ์ธก์ ํญ๋ชฉ์ด ๊ธฐ๋ก๋๊ณ ๋ฉ์๋ ํธ์ถ์ด ํฌํจ๋ ํธ๋์ญ์
์ถ์ ํญ๋ชฉ์ด ๊ธฐ๋ก๋ฉ๋๋ค.
์ปค์คํ
๋ฐ์ดํฐ์คํ ์ด
Ruby ์์ด์ ํธ๋ ๋ฐ์ดํฐ ์ ์ฅ์์ ๋ํ ํธ์ถ์ ๋
น์ํ๊ธฐ ์ํ ํน์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ SQL ๋ฐ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ชจ๋ ์ง์ํ๊ณ ํ์ฌ gem์์ ์ฌ์ฉํ ์ ์๋ ์ผ๊ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ธฐ ์ํ ๊ฒ์
๋๋ค.
NewRelic::Agent::Datastores ๋ชจ๋ ํจ์๋ฅผ ํตํด ๊ธฐ๋ก๋ ์ธก์ ํญ๋ชฉ์ New Relic์ Databases UI์ ํ์๋ฉ๋๋ค.
trace ๋ฉ์๋์ ๋ํ Datastore๋ฅผ ๊ธฐ๋กํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์
๋๋ค.
NewRelic::Agent::Datastores.trace self, :find, "FauxDB"
์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ๊ณ์ธกํ ํด๋์ค, ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ์ฐพ์ ๋ฉ์๋, ์ธ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ๋ฐ์ดํฐ ์ ์ฅ์ ์ ํ ์ด๋ฆ์
๋๋ค. ์ ํ์ ์์
์ด๋ฆ์ด ์ต์ข
๋งค๊ฐ๋ณ์๋ก ํฌํจ๋ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฉ์๋ ์ด๋ฆ์ด ๋ฉํธ๋ฆญ์์ ์์
์ ๋ํ๋ด๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์ด ์ธํฐํ์ด์ค๋ก ๊ธฐ๋ก๋ Datastore ์ธก์ ํญ๋ชฉ์ ์ปฌ๋ ์
/ํ
์ด๋ธ ์ด๋ฆ ์ถ๊ฐ๋ฅผ ํ์ฉํ์ง ์์ต๋๋ค. ์ด๋ฅผ ์ํด ์๋์ wrap ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ์ธ์.
wrap ์ธก์ ํญ๋ชฉ ์ด๋ฆ์ ์ถ๊ฐ ์ปฌ๋ ์
/ํ
์ด๋ธ ์ ๋ณด๊ฐ ํฌํจ๋ Datastore ์ธก์ ํญ๋ชฉ์ ๊ธฐ๋กํ ์ ์์ต๋๋ค. ๋ํ ๋๋ฆฐ ๋ฌธ์ ์์์ฐจ๋ฆฌ๋ ๊ฒ๊ณผ ๊ฐ์ ์์
์ ๋ํ ์ฝ๋ฐฑ์ ์ ๊ณตํฉ๋๋ค.
NewRelic::Agent::Datastores.wrap("FauxDB", "find", table) do
๋ฐ์ดํฐ ์ ์ฅ์ ํธ์ถ์ ๋ํ ์ถ๊ฐ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ค๋ฉด wrap ์์ ์ ํ์ ์ฝ๋ฐฑ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
callback = Proc.new do |result, scoped_metric, elapsed|
NewRelic::Agent::Datastores.notice_sql(query, scoped_metric, elapsed)
NewRelic::Agent::Datastores.wrap("FauxDB", "find", "items", callback) do
์ด ๋์ฐ๋ฏธ ๋ฉ์๋๋ ํธ๋์ญ์
์ถ์ ๋ฐ ๋๋ฆฐ SQL ํ์ด์ง์ ํ์ํ๊ธฐ ์ํด ๋๋ฆฐ SQL ์ฟผ๋ฆฌ๋ฅผ ๊ธฐ๋กํฉ๋๋ค. SQL์ ์ฌ์ฉ์ ์ค์ ์ ๋ฐ๋ผ ํํฐ๋ง๋๊ณ ๋๋
ํ๋ฉ๋๋ค.
NewRelic::Agent::Datastores.notice_sql(query, scoped_metric, elapsed)
๋น SQL ์ฟผ๋ฆฌ๋ notice_sql ๋ฅผ ํตํด ๋ณด๋ด์ง ์์์ผ ํฉ๋๋ค. ๋์ notice_statement ๋ฅผ ์ฌ์ฉํ์ธ์.
์ฃผ์
New Relic์ ํธ๋์ญ์
์ถ์ ๋ฐ ๋๋ฆฐ SQL ๊ธฐ๋ฅ์ ์ ๋ฌ๋ ์ฟผ๋ฆฌ์ ๋๋
ํ๋ฅผ ์ ์ฉํ๋ ค๊ณ ์๋ํ์ง๋ง ์ฟผ๋ฆฌ ํ์์ด ์ง์๋์ง ์์ ์บก์ฒ๋ ์ฟผ๋ฆฌ์ ํฌํจ๋ ์ฌ์ฉ์ ์ ๋ณด๊ฐ ๋
ธ์ถ๋ ์ ์์ต๋๋ค.
์ด ๋์ฐ๋ฏธ ๋ฉ์๋๋ ํธ๋์ญ์
์ถ์ ์ ๋ํ ๋๋ฆฐ ๋ฐ์ดํฐ ์ ์ฅ์ ํธ์ถ์ ๋ํ ๋ฌธ์ ๊ธฐ๋กํฉ๋๋ค. ์ด๊ฒ๋ค์ ๋๋
ํ ๋์ง ์์ต๋๋ค .
NewRelic::Agent::Datastores.notice_statement(statement, elapsed)
SQL ์ฟผ๋ฆฌ๋ notice_statement ๋ฅผ ํตํด ์ ์ก๋์ด์๋ ์ ๋ฉ๋๋ค. ๋์ notice_sql ์(๋ฅผ) ์ฌ์ฉํ์ญ์์ค.
์ฃผ์
์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉ์๊ฐ ์ฟผ๋ฆฌ ์บก์ฒ๋ฅผ ๊ป์ ๋ ๋ช
๋ น๋ฌธ์ ์ ์ ํ๊ฒ ๋ฌด์ํ์ง๋ง ์์์ ๋ฐ์ดํฐ๋ฅผ ๋๋
ํํ ์๋ ์์ต๋๋ค! ์บก์ฒ๋ ์ฟผ๋ฆฌ์ ํฌํจ๋ ์ฌ์ฉ์ ์ ๋ณด๊ฐ ๋
ธ์ถ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด ๋ฉ์๋์ ์ ๋ฌ๋ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ New Relic์ผ๋ก ์ ์กํ๊ธฐ์ ์์ ํ์ง ํ์ธํฉ๋๋ค.
ํ์ฅ ํ
์คํธ
New Relic์ ํ์ฅํ๋ gem์ ์์ฑํ ๋ ์๋ํ๋ ํ
์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์์ด์ ํธ ์์ฒด์์ ์ฌ์ฉํ๋ ํ
์คํธ ๋์ฐ๋ฏธ๋ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํ
์คํธ ์์
์ ๋จ์ํํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ์น์
์ ์ค๋ช
๋ ํ
์คํธ ๋ฉ์๋๋ ํ
์คํธ ์ฝ๋(๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก test_helper.rb ํ์ผ)์์ ์ด๋ฅผ ํธ์ถํ์ฌ ์ก์ธ์คํ ์ ์์ต๋๋ค.
NewRelic::Agent.require_test_helper
์ด ๋ฐฉ๋ฒ์ ์์ ๋ฉํธ๋ฆญ์ด Ruby ์์ด์ ํธ์ ์ํด ๊ธฐ๋ก๋๋๋ก ํ๋ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ์
๋๋ค. refute_metrics_recorded ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ๊ฐ๋จํ ํํ๋ก assert_metrics_recorded ์ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ ์ ์์ต๋๋ค.
assert_metrics_recorded(["MetricA", "MetricB"])
ํน์ ๊ฐ์ด ์๋ ๋ฉํธ๋ฆญ์ ๋ค์ ๊ตฌ๋ฌธ์ ํตํด ์ด์ค์
๋ ์ ์์ต๋๋ค.
assert_metrics_recorded('MetricA' => {
:total_call_time => 1.0 })
์ด๋ฌํ ๋ฉ์๋๋ ์น ๋๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํธ๋์ญ์
์์ ์คํ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค.
with_config ์(๋ฅผ) ํตํด ํ
์คํธ๋ฅผ ์ํด ์์ด์ ํธ ๊ตฌ์ฑ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์์ด์ ํธ์ ๋ค๋ฅธ ๊ตฌ์ฑ ๊ฐ์ ์ ์ฉ๋๋ ํด์๋ฅผ ์ทจํฉ๋๋ค.
with_config(:enabled => false) do
ํ
์ด ๋ฐฉ๋ฒ์ ๊ณ์ธก ์ค์น๋ฅผ ํ
์คํธํ๋ ๋ฐ ๋์์ด ๋์ง ์์ต๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก require ์์ ๊ณ์ธก์ด ๋ฐ์ํ ๋ ํ์ธ๋๊ณ ํ
์คํธ์ ์ค์ ๋ณ๊ฒฝ์ ์ํฅ์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
์ฌ๋ฌ gem ๋ฒ์ ์ ๋ํด ํ์ฅ์ ํ
์คํธํด์ผ ํ๋ ๊ฒฝ์ฐ Ruby ์์ด์ ํธ ์์ฒด ํ
์คํธ ์ฝ๋์ ์ผ๋ถ์ธ Multiverse๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ค์ค ์ฐ์ฃผ ํ
์คํธ์ ์ ๋ ์์ด์ ํธ ํ์ผ์ suites ๋๋ ํ ๋ฆฌ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
์์ ์ gem์ ๋ํด Multiverse๋ฅผ ๊ตฌ์ฑํ๋ ค๋ฉด:
Require tasks/multiverse in Rakefile. rake test:multiverse ๋ช
๋ น์ ํ์ฑํํ๋ ค๋ฉด Rakefile์ ๋ค์์ ์ถ๊ฐํ์ธ์.
require "tasks/multiverse"
Create the Multiverse test directory. ๋ค์ค ์ฐ์ฃผ ํ
์คํธ์๋ ํน์ ํ์ผ ๋ ์ด์์์ด ํ์ํฉ๋๋ค. ๋ค์ ํ์ผ ์์น๋ฅผ ์ฌ์ฉํ์ฌ test/multiverse/YOUR_PROJECT ์ด๋ผ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ญ๋๋ค.
test/multiverse/YOUR_PROJECT
test/multiverse/YOUR_PROJECT/Envfile
test/multiverse/YOUR_PROJECT/config/newrelic.yml
test/multiverse/YOUR_PROJECT/FILE_WITH_A_TEST.rb
Configure your Envfile. Multiverse ํ
์คํธ๋ฅผ ์ํด gem ์์กด์ฑ/์ข
์์ฑ ์ธํธ๋ฅผ ์ ์ธํ๋ ค๋ฉด Envfile ๋ฅผ ์ฌ์ฉํ์ธ์. ์๋ฅผ ๋ค์ด, Envfile ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
gem 'your-project', '~> 1.0.0'
gem 'newrelic_your-project', path: '../../..'
gem 'your-project', '~> 2.1.0'
gem 'newrelic_your-project', path: '../../..'
ํ
Multiverse ํ
์คํธ๊ฐ ์๋ํ๋์ง ํ์ธํ๋ ค๋ฉด newrelic_rpm ๋ฐ rack ์ ๋ํด gem ์ค์ ํฌํจํฉ๋๋ค.
Detect dependencies. ํ์ํ ๊ฒฝ์ฐ Multiverse ํ
์คํธ์์ ์ถ๊ฐ ์์กด์ฑ/์ข
์์ฑ ๊ฐ์ง๋ฅผ ์คํํ์ฌ ํ์ฅ ํ๋ก๊ทธ๋จ์ ๋ฆฌ์์ค๊ฐ ๋ก๋๋์๋์ง ํ์ธํ์ธ์.
require 'newrelic/your-project'
DependencyDetection.detect!
class YourProjectTest > Minitest::Test
Envfile ์ gem ์์กด์ฑ/์ข
์์ฑ์ ๋ํด Multiverse ํ
์คํธ๋ฅผ ์คํํ๋ ค๋ฉด ๋ค์์ ์ํํ์ธ์.
- Gem์ ๋ํด Multiverse๋ฅผ ์ค์ ํ ํ
rake test:multiverse ์ ์คํํ์ฌ ๋๋ ํฐ๋ฆฌ์์ ํ
์คํธ๋ฅผ ์คํํฉ๋๋ค.