Rubyã®OpenTelemetryãã¬ã¼ã¹æåè¨è£ ã¨OpenTelemetry Collectorã®ãµã³ããªã³ã°ã試ãã¦ã¿ã
Ruby on Railsã®OpenTelemetryãã¬ã¼ã¹èªåè¨è£ ã試ãããã ãã©ãè³æ¥µç°¡åããã¦ç¹æ®µæ¸ããã¨ããªãã£ãï¼ãµã³ãã«ã³ã¼ãï¼ãmrasuããã®OpenTelemetryã§Rubyã使ãæã®ç¡é£ãªè¨å®ã«å ¨é¨æ¸ãã¦ãã£ããããã
ï¼â»ãã¨ããèãããèªåè¨è£ ã¨ãããzero-codeè¨è£ ãããªãã¦ãã©ã¤ãã©ãªã§ã®è¨è£ ã ã£ããªããããã«ããã¤ã³ãã¼ãããã ãã§ãã以ä¸ã¯ä½ãããã¨ãè¨è£ ããããï¼
Rubyã§ã®æåè¨è£
èªåè¨è£ ã®æ¬¡ã¯æåè¨è£ ãæ¼ããã¦ããããã¨ããããã§ã·ã³ãã«ãªããã°ã©ã ãæ¸ãã¦å®é¨ãã¦ã¿ãã
require 'opentelemetry/sdk' require 'opentelemetry/exporter/otlp' # Uncomment to use all instrumentation # require 'opentelemetry/instrumentation/all' def otel_config OpenTelemetry::SDK.configure do |c| c.service_name = 'tiny-ruby-trace-sample' c.service_version = '1.0.0' c.resource = OpenTelemetry::SDK::Resources::Resource.create( OpenTelemetry::SemanticConventions::Resource::DEPLOYMENT_ENVIRONMENT => 'development', OpenTelemetry::SemanticConventions::Resource::HOST_NAME => Socket.gethostname ) c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( endpoint: 'http://localhost:4318/v1/traces' ) ) ) # Uncomment to use all instrumentation # c.use_all end end def main $stdout.sync = true tracer = OpenTelemetry.tracer_provider.tracer('tiny-ruby-trace-sample') print "start (PID #{$$}): " 1.upto(20) do |i| tracer.in_span('main') do |span| span.set_attribute('myname', "parent-#{i}") span.set_attribute('parameter', Time.now.to_f.to_s) print '+' 1.upto(4) do |i2| tracer.in_span('child') do |child_span| child_span.set_attribute('myname', "child-#{i}-#{i2}") child_span.set_attribute('parameter', Time.now.to_f.to_s) if i % 8 == 0 && i2 == 2 error_msg = "forced error #{$$}" child_span.record_exception(StandardError.new(error_msg)) child_span.status = OpenTelemetry::Trace::Status.error(error_msg) sleep(1 + rand(0.5)) print 'E' else sleep(0.1 + rand(0.1)) print '.' end end end end end OpenTelemetry.tracer_provider.shutdown puts '' end otel_config main
SDKã®è¨å®ã¯Railsã¨åããOpenTelemetry.trace_provider.tracer
ã«ãµã¼ãã¹åãæå®ãã¦ãã¬ã¼ãµãªãã¸ã§ã¯ããä½ã£ã¦ããã¨ã¯ãã®ãªãã¸ã§ã¯ãã®in_span
ã®ãããã¯ç¯å²ã§ã¹ãã³ãä½ãããããããã¯å
ã§ããã«in_span
ã使ãã°åã¹ãã³ã«ãªããç°¡åã
å±æ§ã»å¤ã¯ã¹ãã³ãªãã¸ã§ã¯ãã®set_attribute
ã§è¨å®ãããã¨ã©ã¼ãè¨é²ãããã¨ãã«ã¯ãã¹ãã³ãªãã¸ã§ã¯ãã®record_exception
ã«Exceptionãªãã¸ã§ã¯ããæå®ããï¼å±æ§ãattributes
ãã©ã¡ã¼ã¿ã§æå®ã§ããããã ï¼ã
record_exception
ã§ã¯status codeãå¤ãã£ã¦ãããªãã£ãã®ã§ãstatus
ãOpenTelemetry::Trace::Status.error
ã«ãã¦ãããã©ã¡ããã¨ã©ã¼ã¤ãã³ãã¡ãã»ã¼ã¸åãã®å¼æ°ãã¨ãã®ã§record_exception
ã¨ã®æ£²ã¿åããå¾®å¦ã«é£ããããã·ã³ãã«ã«æ¸ã¾ãããªãstatus
ã ãã§ããããexceptionã®è©³ç´°ãå
¥ããããã°record_exception
ãä½µç¨ããã¨ãããã¨ãããã¨ããªã
å½åãã¢ããªã±ã¼ã·ã§ã³ãå®è¡ãã¦ããã¬ã¼ã¹ãªãã¸ã§ã¯ãã®ä½æã¾ã§ã¯é 調ã«é²ãã§ããã®ã«4318ãã¼ãã¸ã®ãã¹ããå
¨ç¶ãªãã¦æ©ãã§ãããçµå±ãtracer_providerã¯ãããã¯çµäºæã«ãããã¡ã«ãããã®ããã©ãã·ã¥ãã¦ãããããã§ã¯ãªãã®ã§ã常é§ããã«çµäºããå ´åã¯shutdown
ãå¼ã³åºãã¦ãã©ãã·ã¥ãããã®ãé©åã£ã½ãã
ã¢ããªã±ã¼ã·ã§ã³ã®æåã¨ãã¦ã¯ã20åã®è¦ªãã¬ã¼ã¹ãé ã«å®è¡ãããã®ä¸ã§ã¯ãããã4åã®åãã¬ã¼ã¹ãå®è¡ããã親ãã¬ã¼ã¹ã8çªç®ã»16çªç®ã®ã¨ãããã¤åãã¬ã¼ã¹ã®2çªç®ã§ã¨ã©ã¼ãçºçãããããã«ããã
é²æç¶æ³ãè¦ããªãã¨å¯ããã®ã§ãè¨å·è¡¨ç¤ºããã¦ããã
$ bundle exec ruby main.rb start (PID 2667019): +....+....+....+....+....+....+....+.E..+....+....+....+....+....+....+....+.E..+....+....+....+....
OpenTelemetry Collectorã®ãµã³ããªã³ã°
åããã¹ãã§OpenTelemetry CollectorãOTLPã®httpåãå£ã§ç«ã¦ã¦ããã°ãã¢ããªã±ã¼ã·ã§ã³ã®ãã¬ã¼ã¹ãåãåããã¨ãã§ãããããã¦ãããJaegerãMackerel Vaxilaã«ããã«éããã¨ãã§ããã
ãã¬ã¼ã¹ã¯ä¾¿å©ã ãã大éã«éãã¨èªåãã¹ãã§ããã°ã¹ãã¬ã¼ã¸ãå§è¿«ããããSaaSãªãã³ã¹ãã«ããã£ã¦ããããã®ãã¬ã¼ããªããã©ããããã¨ããã®ã¯ä»å¾æ¥åã§åããããã¨ã¯ééããªãã®ã§ããã®ãããªã±ã¼ã¹ã®ä»£è¡¨çãªæ段ã§ãããµã³ããªã³ã°ã«ã¤ãã¦å°ã触ã£ã¦ãããã¨ã«ããã
OpenTelemetry Collectorã§å¯è½ãªãµã³ããªã³ã°ã¨ãã¦ã¯ã主ã«2種é¡ãããã
- ããããã¼ã¹ãµã³ããªã³ã°ï¼å ¥ã£ã¦ãããã¬ã¼ã¹ã«ã¤ãã¦ã10%ã¨ãã£ã確ççãªãµã³ããªã³ã°ãè¡ããåç´ã§OpenTelemetry Collectorã®åä½ç°å¢ã¸ã®è² è·ã¯ä½ãããã ããé害解æã«éè¦ãªãã¬ã¼ã¹ãè¦è½ã¨ãå¯è½æ§ã¯å¸¸ã«ãã
- ãã¼ã«ãã¼ã¹ãµã³ããªã³ã°ï¼ãã¬ã¼ã¹ãçµäºããã¾ã§å¾ ã£ã¦ãããµã³ããªã³ã°å¯¾è±¡ã«ãããã©ããã決å®ãããã¨ã©ã¼ãå«ããã¬ã¼ã¹ãã¬ã¤ãã³ã·ã¼ã®å¤§ããªãã¬ã¼ã¹ãªã©ãè¦è½ã¨ããããªããã¬ã¼ã¹ã確å®ã«æ¾ããå®å¸¸çãªãã¬ã¼ã¹ãæ¨ã¦ãã¨ãã£ãé«åº¦ãªãµã³ããªã³ã°ãã§ãããä¸æ¹ã§ãä¸å®éã®ãã¬ã¼ã¹ãã¡ã¢ãªã«èç©ãã¦å¦çãããããOpenTelemetry Collectorã®åä½ç°å¢ã¸ã®è² è·ãé«ããæ°´å¹³ã¹ã±ã¼ã«ããã¥ããã¨ããé£ç¹ãããã対象åããªã·ã¼èªä½ã¯äººéãæå®ãããããå½ã¦ã¯ã¾ããªãéè¦ãªãã¬ã¼ã¹ãè¦è½ã¨ãå¯è½æ§ããã
ãã¡ãªããã«ã¤ãã¦ã¯ç¢ºãã«é£ããã¨ããã§ããLearning OpenTelemetryãã§ããµã³ããªã³ã°ã¯ã³ã¹ããæ¬å½ã«åé¡ã«ãªãã¾ã§ãã¹ãã§ãªãã¨æ¸ããã¦ããã
ã¨ã¯ãããç§ã¯ãµã³ããªã³ã°ã試ãã¦ã¿ããã®ã§ããã
ã¾ãã¯ããããã¼ã¹ãµã³ããªã³ã°ãã試ãã¦ã¿ãããããã¯probabilistic_samplerï¼probabilisticsamplerprocessorï¼ã¨ããããã»ããµã対å¿ããã
otel-col.yamlãç¨æããã
receivers: otlp: protocols: http: processors: resource/namespace: attributes: - key: service.namespace value: "kmuto/ruby-otel-trace-test" action: upsert batch: send_batch_size: 5000 send_batch_max_size: 5000 probabilistic_sampler: sampling_percentage: 10 exporters: debug: verbosity: detailed otlphttp/vaxila: endpoint: "https://otlp-vaxila.mackerelio.com" headers: Accept: "*/*" "Mackerel-Api-Key": ${env:MACKEREL_APIKEY} service: pipelines: traces: receivers: [otlp] processors: [probabilistic_sampler, resource/namespace, batch] exporters: [debug, otlphttp/vaxila]
probabilistic_sampler
ã®sampling_percentage
ã§ãµã³ããªã³ã°ç¢ºçãæå®ããã0ãªãå
¨é¨æ£å´ãã100以ä¸ãªãå
¨é¨æ¾ãã
10%ã«è¨å®ããå®éã®å®è¡ã§ã¯ã20ãã¬ã¼ã¹ã®ãã¡ã1ã¤ã ãã®ãã¨ãããã°ã2ã¤ã3ã¤æ¡æããããã¨ãããããã ã£ããããã©ã«ãã§ã¯proportionalã¨ããã¢ã¼ãã使ããã¦ããããã»ãã«hash_seedãequalizingã¨ãããã®ããããæ¾ãåºãæ¹ã«å·®ãããããããããã¥ã¡ã³ããé£è§£ã
ãããã«ãããã¨ã©ã¼ã¹ãã³ã®åå¨æç¡ã¯èæ ®ããããããé害ãçºçãã¦ãããæ¾ãã¦ãããã¯éä»»ãã ããªãã»ã©ã
å¼·å¶çã«ãµã³ããªã³ã°ãããæ¹æ³ã¨ãã¦ãã¹ãã³ã®sampling.priority
å±æ§ã«æ£ã®æ°å¤ï¼ãã¨ãã°100ï¼ãæå®ãã¦å¯¾è±¡ã«ãããã¨ã¯ã§ããï¼ããã§åãåºããããã®ã¯ç¢ºçã®ç¯å²å¤ã«ããªãããã ï¼ããã ãåã¹ãã³ã«ãããæå®ãã¦ãåã¹ãã³åç¬ã®ãã¬ã¼ã¹ã«ãªã£ã¦ãã¾ãã使ãåæã¨ãã¦ã¯å¾®å¦ãªã¨ãããèªåãä½ãééã£ã¦ããå¯è½æ§ãããã
次ã«ãã¼ã«ãã¼ã¹ãµã³ããªã³ã°ã試ãããããã¯tail_samplingï¼tailsamplingprocessorï¼ããã»ããµã¨ãªãã
# dist/otelcol-ruby-tracer --config otel-col.yaml receivers: otlp: protocols: http: processors: resource/namespace: attributes: - key: service.namespace value: "kmuto/ruby-otel-trace-test" action: upsert batch: send_batch_size: 5000 send_batch_max_size: 5000 tail_sampling: policies: - name: error-spans type: status_code status_code: status_codes: [ERROR] - name: sampling type: probabilistic probabilistic: sampling_percentage: 40 exporters: debug: verbosity: detailed otlphttp/vaxila: endpoint: "https://otlp-vaxila.mackerelio.com" headers: Accept: "*/*" "Mackerel-Api-Key": ${env:MACKEREL_APIKEY} service: pipelines: traces: receivers: [otlp] processors: [tail_sampling, resource/namespace, batch] exporters: [debug, otlphttp/vaxila]
tail_sampling
ã®policies
ã§ããªã·ã¼ãå®ç¾©ãã¦ãããtype
ã§ä½¿ãããããªã·ã¼ãé¸ã³ããã®ãã©ã¡ã¼ã¿ãè¨è¿°ãããããã¥ã¡ã³ããè¦ãã ã«ãªããªãæãã代ç©ã§ãç¹ã«andãcompositeã¯ãã¾ã触ããããªããªãâ¦â¦ã
policies
ã¯é
åã«ãªã£ã¦ãã¦ãå®ç¾©ããé ã«è©ä¾¡ããã¦ãããåè´ãããã®ã¯æ¬¡ã®ããªã·ã¼ã«ã¯é²ã¾ãã«ããã§ééã¨ãªãããã ã
ããã§ã¯2ã¤ã®ããªã·ã¼ãç¨æãã¦ã¿ãã
- error-spansï¼status_codeããªã·ã¼ãå©ç¨ãã¹ãã³ã®status codeã
ERROR
ã ã£ãããµã³ããªã³ã°å¯¾è±¡ã¨ãããstatus_code
ããããã«status_codes
ã®åãæã¤ã®ãããããããï¼status_code
ã¯ããªã·ã¼ã®ã»ãã®ååãªã®ã§ä»æ¹ãªããï¼ - samplingï¼probabilisticããªã·ã¼ãå©ç¨ãããã¯ããããã¼ã¹ãµã³ããªã³ã°ã§ä½¿ã£ã¦ããã®ã¨åæ§ã«ã確ççã«ãµã³ããªã³ã°ããï¼å
ã®probabilistic_samplerã¨ã®éãã¯ããã¥ã¡ã³ãã«ãã£ã¡ãæ¸ããã¦ããï¼ã
sampling_percentage
ã§ç¢ºçãæå®ããã
ã¨ã©ã¼ã¹ãã³ãå«ããã¬ã¼ã¹ã¯ç¢ºå®ã«åå¾ããæ®ãã«ã¤ãã¦ã¯40%ã®ç¢ºçã§ãµã³ããªã³ã°ããã¨ããæ§æã ã
ã¢ããªã±ã¼ã·ã§ã³ãå®è¡ããã¨ãã¨ã©ã¼ã¹ãã³ãå«ããã¬ã¼ã¹2ã¤ããã£ããä¿æããã¦ããããã以å¤ã®ãã¬ã¼ã¹ã¯7ã8åã¨æå¾ ã©ããã®æåã«ãªã£ã¦ããã
ã²ã¨ã¾ãRubyã§å®é¨ã®ããã®ã¢ããªã±ã¼ã·ã§ã³ãã§ãã¦ãããããã¼ã¹ãµã³ããªã³ã°ããã¼ã«ãã¼ã¹ãµã³ããªã³ã°ã®ä¸¡æ¹ã試ããã¨ãã§ãããå®éã®éç¨ãæ³å®ããã¨ããã¼ã«ãã¼ã¹ãµã³ããªã³ã°ã«ã¤ãã¦ã¯ãã£ã¨è©³ç´°ã«ã¤ãã¦ããããªããç¥ãå¿ è¦ããããã»ãã®ããã»ããµã«ã¤ãã¦ãç¥è¦ãæ·±ããªããã°ãªããªããã§ããã