ddtrace 1.12.1 → 1.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +613 -9
- data/LICENSE-3rdparty.csv +1 -1
- data/bin/ddprofrb +15 -0
- data/bin/ddtracerb +3 -1
- data/ext/{ddtrace_profiling_loader/ddtrace_profiling_loader.c → datadog_profiling_loader/datadog_profiling_loader.c} +2 -2
- data/ext/{ddtrace_profiling_loader → datadog_profiling_loader}/extconf.rb +3 -3
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/NativeExtensionDesign.md +3 -5
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id.h +0 -3
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_from_pthread.c +3 -22
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_noop.c +0 -1
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_cpu_and_wall_time_worker.c +338 -108
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +422 -0
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +101 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.c +22 -14
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.h +4 -0
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.c +3 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.c +111 -118
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.h +11 -4
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.c +545 -144
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.h +3 -2
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/extconf.rb +68 -17
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1047 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.h +166 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/helpers.h +6 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/http_transport.c +60 -32
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +62 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +42 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/native_extension_helpers.rb +50 -4
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.c +155 -32
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.h +16 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/profiling.c +19 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +267 -0
- data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/ruby_helpers.h +33 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +1040 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.h +27 -0
- data/ext/datadog_profiling_native_extension/time_helpers.c +53 -0
- data/ext/datadog_profiling_native_extension/time_helpers.h +26 -0
- data/lib/datadog/appsec/assets/waf_rules/processors.json +92 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +698 -75
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +114 -0
- data/lib/datadog/appsec/assets/waf_rules/strict.json +98 -8
- data/lib/datadog/appsec/assets.rb +8 -0
- data/lib/datadog/appsec/component.rb +21 -2
- data/lib/datadog/appsec/configuration/settings.rb +167 -189
- data/lib/datadog/appsec/configuration.rb +0 -79
- data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
- data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +54 -0
- data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
- data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
- data/lib/datadog/appsec/contrib/devise/tracking.rb +57 -0
- data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +6 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +8 -6
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +3 -8
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +3 -6
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +3 -6
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +3 -2
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +77 -27
- data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
- data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -11
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +3 -6
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
- data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -4
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +13 -7
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +3 -6
- data/lib/datadog/appsec/event.rb +106 -50
- data/lib/datadog/appsec/extensions.rb +1 -130
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -3
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +3 -6
- data/lib/datadog/appsec/processor/actions.rb +49 -0
- data/lib/datadog/appsec/processor/rule_loader.rb +60 -0
- data/lib/datadog/appsec/processor/rule_merger.rb +22 -2
- data/lib/datadog/appsec/processor.rb +35 -7
- data/lib/datadog/appsec/rate_limiter.rb +1 -1
- data/lib/datadog/appsec/remote.rb +17 -11
- data/lib/datadog/appsec/response.rb +82 -4
- data/lib/datadog/appsec/sample_rate.rb +21 -0
- data/lib/datadog/appsec.rb +3 -4
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/backport.rb +51 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +38 -29
- data/lib/datadog/core/configuration/base.rb +6 -16
- data/lib/datadog/core/configuration/components.rb +20 -7
- data/lib/datadog/core/configuration/ext.rb +28 -5
- data/lib/datadog/core/configuration/option.rb +271 -21
- data/lib/datadog/core/configuration/option_definition.rb +73 -32
- data/lib/datadog/core/configuration/options.rb +27 -15
- data/lib/datadog/core/configuration/settings.rb +398 -119
- data/lib/datadog/core/configuration.rb +24 -4
- data/lib/datadog/core/diagnostics/environment_logger.rb +132 -235
- data/lib/datadog/core/environment/class_count.rb +6 -6
- data/lib/datadog/core/environment/execution.rb +103 -0
- data/lib/datadog/core/environment/ext.rb +13 -11
- data/lib/datadog/core/environment/git.rb +25 -0
- data/lib/datadog/core/environment/identity.rb +18 -48
- data/lib/datadog/core/environment/platform.rb +7 -1
- data/lib/datadog/core/environment/variable_helpers.rb +0 -69
- data/lib/datadog/core/environment/yjit.rb +58 -0
- data/lib/datadog/core/error.rb +1 -0
- data/lib/datadog/core/git/ext.rb +6 -23
- data/lib/datadog/core/logging/ext.rb +3 -1
- data/lib/datadog/core/metrics/ext.rb +7 -5
- data/lib/datadog/core/remote/client/capabilities.rb +7 -2
- data/lib/datadog/core/remote/client.rb +3 -0
- data/lib/datadog/core/remote/component.rb +52 -48
- data/lib/datadog/core/remote/configuration/content.rb +28 -1
- data/lib/datadog/core/remote/configuration/repository.rb +3 -1
- data/lib/datadog/core/remote/ext.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +20 -7
- data/lib/datadog/core/remote/tie/tracing.rb +39 -0
- data/lib/datadog/core/remote/tie.rb +27 -0
- data/lib/datadog/core/remote/transport/config.rb +60 -0
- data/lib/datadog/core/remote/transport/http/api/instance.rb +39 -0
- data/lib/datadog/core/remote/transport/http/api/spec.rb +21 -0
- data/lib/datadog/core/remote/transport/http/api.rb +58 -0
- data/lib/datadog/core/remote/transport/http/builder.rb +219 -0
- data/lib/datadog/core/remote/transport/http/client.rb +48 -0
- data/lib/datadog/core/remote/transport/http/config.rb +280 -0
- data/lib/datadog/core/remote/transport/http/negotiation.rb +146 -0
- data/lib/datadog/core/remote/transport/http.rb +179 -0
- data/lib/datadog/core/{transport → remote/transport}/negotiation.rb +25 -23
- data/lib/datadog/core/remote/worker.rb +11 -5
- data/lib/datadog/core/runtime/ext.rb +22 -12
- data/lib/datadog/core/runtime/metrics.rb +43 -0
- data/lib/datadog/core/telemetry/client.rb +28 -10
- data/lib/datadog/core/telemetry/emitter.rb +9 -11
- data/lib/datadog/core/telemetry/event.rb +250 -44
- data/lib/datadog/core/telemetry/ext.rb +8 -1
- data/lib/datadog/core/telemetry/heartbeat.rb +3 -7
- data/lib/datadog/core/telemetry/http/ext.rb +13 -8
- data/lib/datadog/core/telemetry/http/response.rb +4 -0
- data/lib/datadog/core/telemetry/http/transport.rb +10 -3
- data/lib/datadog/core/telemetry/request.rb +59 -0
- data/lib/datadog/core/transport/ext.rb +49 -0
- data/lib/datadog/core/transport/http/adapters/net.rb +168 -0
- data/lib/datadog/core/transport/http/adapters/registry.rb +29 -0
- data/lib/datadog/core/transport/http/adapters/test.rb +89 -0
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +83 -0
- data/lib/datadog/core/transport/http/api/endpoint.rb +31 -0
- data/lib/datadog/core/transport/http/api/fallbacks.rb +26 -0
- data/lib/datadog/core/transport/http/api/map.rb +18 -0
- data/lib/datadog/core/transport/http/env.rb +62 -0
- data/lib/datadog/core/transport/http/response.rb +60 -0
- data/lib/datadog/core/transport/parcel.rb +22 -0
- data/lib/datadog/core/transport/request.rb +17 -0
- data/lib/datadog/core/transport/response.rb +64 -0
- data/lib/datadog/core/utils/duration.rb +52 -0
- data/lib/datadog/core/utils/hash.rb +47 -0
- data/lib/datadog/core/utils/network.rb +1 -1
- data/lib/datadog/core/utils/safe_dup.rb +27 -20
- data/lib/datadog/core/utils/url.rb +25 -0
- data/lib/datadog/core/utils.rb +1 -1
- data/lib/datadog/core/workers/async.rb +3 -2
- data/lib/datadog/core/workers/polling.rb +2 -2
- data/lib/datadog/kit/appsec/events.rb +139 -89
- data/lib/datadog/kit/enable_core_dumps.rb +5 -6
- data/lib/datadog/kit/identity.rb +80 -65
- data/lib/datadog/opentelemetry/api/context.rb +10 -3
- data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -3
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +48 -5
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +167 -0
- data/lib/datadog/opentelemetry/trace.rb +58 -0
- data/lib/datadog/opentelemetry.rb +4 -0
- data/lib/datadog/opentracer/text_map_propagator.rb +2 -1
- data/lib/datadog/opentracer.rb +9 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +43 -20
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +3 -1
- data/lib/datadog/profiling/collectors/info.rb +101 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
- data/lib/datadog/profiling/component.rb +248 -97
- data/lib/datadog/profiling/exporter.rb +26 -5
- data/lib/datadog/profiling/ext.rb +2 -12
- data/lib/datadog/profiling/flush.rb +10 -5
- data/lib/datadog/profiling/http_transport.rb +23 -6
- data/lib/datadog/profiling/load_native_extension.rb +25 -6
- data/lib/datadog/profiling/native_extension.rb +1 -22
- data/lib/datadog/profiling/profiler.rb +36 -13
- data/lib/datadog/profiling/scheduler.rb +20 -15
- data/lib/datadog/profiling/stack_recorder.rb +19 -4
- data/lib/datadog/profiling/tag_builder.rb +5 -0
- data/lib/datadog/profiling/tasks/exec.rb +3 -3
- data/lib/datadog/profiling/tasks/help.rb +3 -3
- data/lib/datadog/profiling.rb +28 -79
- data/lib/datadog/tracing/component.rb +70 -11
- data/lib/datadog/tracing/configuration/agent_settings_resolver.rb +13 -0
- data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
- data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
- data/lib/datadog/tracing/configuration/ext.rb +40 -33
- data/lib/datadog/tracing/configuration/http.rb +74 -0
- data/lib/datadog/tracing/configuration/settings.rb +136 -99
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/action_cable/ext.rb +21 -18
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/ext.rb +21 -18
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +10 -7
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +11 -8
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/action_view/ext.rb +13 -10
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +14 -7
- data/lib/datadog/tracing/contrib/active_job/ext.rb +26 -23
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +13 -10
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +29 -15
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +10 -7
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -6
- data/lib/datadog/tracing/contrib/active_record/ext.rb +18 -15
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +106 -202
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +3 -0
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -7
- data/lib/datadog/tracing/contrib/active_support/ext.rb +19 -16
- data/lib/datadog/tracing/contrib/analytics.rb +0 -1
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +15 -7
- data/lib/datadog/tracing/contrib/aws/ext.rb +38 -24
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +16 -5
- data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +20 -0
- data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +14 -14
- data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +3 -10
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +2 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +19 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +22 -0
- data/lib/datadog/tracing/contrib/configurable.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +21 -7
- data/lib/datadog/tracing/contrib/dalli/ext.rb +27 -11
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +17 -8
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +14 -7
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +17 -14
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +15 -7
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +22 -15
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +104 -99
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +17 -9
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +48 -3
- data/lib/datadog/tracing/contrib/ethon/ext.rb +20 -11
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +6 -3
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +20 -10
- data/lib/datadog/tracing/contrib/excon/ext.rb +17 -8
- data/lib/datadog/tracing/contrib/excon/middleware.rb +25 -5
- data/lib/datadog/tracing/contrib/ext.rb +26 -1
- data/lib/datadog/tracing/contrib/extensions.rb +38 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +27 -10
- data/lib/datadog/tracing/contrib/faraday/ext.rb +17 -8
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +22 -6
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/grape/ext.rb +17 -14
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/graphql/ext.rb +8 -5
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +40 -9
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +39 -20
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +37 -18
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +0 -4
- data/lib/datadog/tracing/contrib/grpc/ext.rb +17 -13
- data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
- data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
- data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +5 -8
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +34 -11
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
- data/lib/datadog/tracing/contrib/http/ext.rb +17 -9
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +27 -7
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +34 -11
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +18 -9
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +22 -5
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +34 -11
- data/lib/datadog/tracing/contrib/httprb/ext.rb +17 -9
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +22 -5
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/kafka/ext.rb +43 -39
- data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
- data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
- data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -17
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +15 -7
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +21 -16
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +16 -5
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +22 -14
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +16 -10
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +22 -7
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +53 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +38 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +135 -0
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +23 -14
- data/lib/datadog/tracing/contrib/pg/ext.rb +23 -19
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +49 -9
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +15 -7
- data/lib/datadog/tracing/contrib/presto/ext.rb +26 -20
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +14 -5
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
- data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +13 -8
- data/lib/datadog/tracing/contrib/qless/ext.rb +15 -12
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +22 -12
- data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +10 -7
- data/lib/datadog/tracing/contrib/racecar/event.rb +5 -5
- data/lib/datadog/tracing/contrib/racecar/ext.rb +21 -18
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +17 -12
- data/lib/datadog/tracing/contrib/rack/ext.rb +19 -16
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +63 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +16 -50
- data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +0 -2
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +20 -15
- data/lib/datadog/tracing/contrib/rails/ext.rb +8 -5
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +7 -10
- data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
- data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +14 -10
- data/lib/datadog/tracing/contrib/rake/ext.rb +15 -12
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +18 -9
- data/lib/datadog/tracing/contrib/redis/ext.rb +23 -15
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +5 -40
- data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
- data/lib/datadog/tracing/contrib/redis/tags.rb +16 -7
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +46 -33
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +14 -7
- data/lib/datadog/tracing/contrib/resque/ext.rb +10 -7
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +17 -9
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +16 -8
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +25 -5
- data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
- data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
- data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +4 -20
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/sequel/ext.rb +11 -8
- data/lib/datadog/tracing/contrib/sequel/utils.rb +7 -7
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +15 -8
- data/lib/datadog/tracing/contrib/shoryuken/ext.rb +15 -12
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +19 -11
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +33 -30
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +12 -9
- data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +22 -19
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +15 -8
- data/lib/datadog/tracing/contrib/sneakers/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +10 -6
- data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +16 -13
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
- data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
- data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
- data/lib/datadog/{ci/contrib/cucumber → tracing/contrib/trilogy}/patcher.rb +10 -6
- data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +11 -11
- data/lib/datadog/tracing/contrib.rb +2 -0
- data/lib/datadog/tracing/correlation.rb +29 -12
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +165 -0
- data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
- data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/datadog.rb +0 -1
- data/lib/datadog/tracing/distributed/propagation.rb +35 -34
- data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
- data/lib/datadog/tracing/metadata/ext.rb +9 -6
- data/lib/datadog/tracing/metadata/tagging.rb +3 -3
- data/lib/datadog/tracing/remote.rb +78 -0
- data/lib/datadog/tracing/sampling/matcher.rb +23 -3
- data/lib/datadog/tracing/sampling/rule.rb +7 -2
- data/lib/datadog/tracing/sampling/rule_sampler.rb +31 -0
- data/lib/datadog/tracing/span_operation.rb +3 -15
- data/lib/datadog/tracing/sync_writer.rb +3 -3
- data/lib/datadog/tracing/trace_digest.rb +31 -0
- data/lib/datadog/tracing/trace_operation.rb +17 -5
- data/lib/datadog/tracing/trace_segment.rb +5 -2
- data/lib/datadog/tracing/tracer.rb +12 -1
- data/lib/datadog/{core → tracing}/transport/http/api/instance.rb +1 -1
- data/lib/datadog/{core → tracing}/transport/http/api/spec.rb +1 -1
- data/lib/datadog/tracing/transport/http/api.rb +43 -0
- data/lib/datadog/{core → tracing}/transport/http/builder.rb +13 -68
- data/lib/datadog/tracing/transport/http/client.rb +57 -0
- data/lib/datadog/tracing/transport/http/statistics.rb +47 -0
- data/lib/datadog/tracing/transport/http/traces.rb +152 -0
- data/lib/datadog/tracing/transport/http.rb +125 -0
- data/lib/datadog/tracing/transport/io/client.rb +89 -0
- data/lib/datadog/tracing/transport/io/response.rb +27 -0
- data/lib/datadog/tracing/transport/io/traces.rb +101 -0
- data/lib/datadog/tracing/transport/io.rb +30 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +126 -0
- data/lib/datadog/tracing/transport/statistics.rb +77 -0
- data/lib/datadog/tracing/transport/trace_formatter.rb +240 -0
- data/lib/datadog/tracing/transport/traces.rb +224 -0
- data/lib/datadog/tracing/workers/trace_writer.rb +6 -4
- data/lib/datadog/tracing/workers.rb +4 -2
- data/lib/datadog/tracing/writer.rb +5 -2
- data/lib/datadog/tracing.rb +8 -2
- data/lib/ddtrace/transport/ext.rb +22 -14
- data/lib/ddtrace/version.rb +9 -12
- data/lib/ddtrace.rb +1 -1
- metadata +157 -139
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +0 -25
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -110
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +0 -591
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +0 -14
- data/ext/ddtrace_profiling_native_extension/time_helpers.c +0 -17
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +0 -10
- data/lib/datadog/ci/configuration/components.rb +0 -32
- data/lib/datadog/ci/configuration/settings.rb +0 -53
- data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -33
- data/lib/datadog/ci/contrib/cucumber/ext.rb +0 -20
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +0 -94
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +0 -28
- data/lib/datadog/ci/contrib/cucumber/integration.rb +0 -47
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -33
- data/lib/datadog/ci/contrib/rspec/example.rb +0 -68
- data/lib/datadog/ci/contrib/rspec/ext.rb +0 -19
- data/lib/datadog/ci/contrib/rspec/integration.rb +0 -48
- data/lib/datadog/ci/contrib/rspec/patcher.rb +0 -27
- data/lib/datadog/ci/ext/app_types.rb +0 -9
- data/lib/datadog/ci/ext/environment.rb +0 -575
- data/lib/datadog/ci/ext/settings.rb +0 -10
- data/lib/datadog/ci/ext/test.rb +0 -35
- data/lib/datadog/ci/extensions.rb +0 -19
- data/lib/datadog/ci/flush.rb +0 -38
- data/lib/datadog/ci/test.rb +0 -81
- data/lib/datadog/ci.rb +0 -20
- data/lib/datadog/core/configuration/dependency_resolver.rb +0 -28
- data/lib/datadog/core/configuration/option_definition_set.rb +0 -22
- data/lib/datadog/core/configuration/option_set.rb +0 -10
- data/lib/datadog/core/telemetry/collector.rb +0 -231
- data/lib/datadog/core/telemetry/v1/app_event.rb +0 -52
- data/lib/datadog/core/telemetry/v1/application.rb +0 -92
- data/lib/datadog/core/telemetry/v1/configuration.rb +0 -25
- data/lib/datadog/core/telemetry/v1/dependency.rb +0 -43
- data/lib/datadog/core/telemetry/v1/host.rb +0 -59
- data/lib/datadog/core/telemetry/v1/integration.rb +0 -64
- data/lib/datadog/core/telemetry/v1/product.rb +0 -36
- data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -106
- data/lib/datadog/core/transport/config.rb +0 -58
- data/lib/datadog/core/transport/http/api.rb +0 -57
- data/lib/datadog/core/transport/http/client.rb +0 -45
- data/lib/datadog/core/transport/http/config.rb +0 -268
- data/lib/datadog/core/transport/http/negotiation.rb +0 -144
- data/lib/datadog/core/transport/http.rb +0 -169
- data/lib/datadog/core/utils/object_set.rb +0 -43
- data/lib/datadog/core/utils/string_table.rb +0 -47
- data/lib/datadog/profiling/backtrace_location.rb +0 -34
- data/lib/datadog/profiling/buffer.rb +0 -43
- data/lib/datadog/profiling/collectors/old_stack.rb +0 -301
- data/lib/datadog/profiling/encoding/profile.rb +0 -41
- data/lib/datadog/profiling/event.rb +0 -15
- data/lib/datadog/profiling/events/stack.rb +0 -82
- data/lib/datadog/profiling/old_recorder.rb +0 -107
- data/lib/datadog/profiling/pprof/builder.rb +0 -125
- data/lib/datadog/profiling/pprof/converter.rb +0 -102
- data/lib/datadog/profiling/pprof/message_set.rb +0 -16
- data/lib/datadog/profiling/pprof/payload.rb +0 -20
- data/lib/datadog/profiling/pprof/pprof.proto +0 -212
- data/lib/datadog/profiling/pprof/pprof_pb.rb +0 -81
- data/lib/datadog/profiling/pprof/stack_sample.rb +0 -139
- data/lib/datadog/profiling/pprof/string_table.rb +0 -12
- data/lib/datadog/profiling/pprof/template.rb +0 -118
- data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +0 -43
- data/lib/datadog/profiling/trace_identifiers/helper.rb +0 -45
- data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
- data/lib/ddtrace/transport/http/adapters/net.rb +0 -168
- data/lib/ddtrace/transport/http/adapters/registry.rb +0 -27
- data/lib/ddtrace/transport/http/adapters/test.rb +0 -85
- data/lib/ddtrace/transport/http/adapters/unix_socket.rb +0 -77
- data/lib/ddtrace/transport/http/api/endpoint.rb +0 -29
- data/lib/ddtrace/transport/http/api/fallbacks.rb +0 -24
- data/lib/ddtrace/transport/http/api/instance.rb +0 -35
- data/lib/ddtrace/transport/http/api/map.rb +0 -16
- data/lib/ddtrace/transport/http/api/spec.rb +0 -17
- data/lib/ddtrace/transport/http/api.rb +0 -39
- data/lib/ddtrace/transport/http/builder.rb +0 -176
- data/lib/ddtrace/transport/http/client.rb +0 -52
- data/lib/ddtrace/transport/http/env.rb +0 -58
- data/lib/ddtrace/transport/http/response.rb +0 -58
- data/lib/ddtrace/transport/http/statistics.rb +0 -43
- data/lib/ddtrace/transport/http/traces.rb +0 -144
- data/lib/ddtrace/transport/http.rb +0 -117
- data/lib/ddtrace/transport/io/client.rb +0 -85
- data/lib/ddtrace/transport/io/response.rb +0 -25
- data/lib/ddtrace/transport/io/traces.rb +0 -99
- data/lib/ddtrace/transport/io.rb +0 -28
- data/lib/ddtrace/transport/parcel.rb +0 -20
- data/lib/ddtrace/transport/request.rb +0 -15
- data/lib/ddtrace/transport/response.rb +0 -60
- data/lib/ddtrace/transport/serializable_trace.rb +0 -122
- data/lib/ddtrace/transport/statistics.rb +0 -75
- data/lib/ddtrace/transport/trace_formatter.rb +0 -198
- data/lib/ddtrace/transport/traces.rb +0 -216
- /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.h +0 -0
- /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.c +0 -0
- /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.h +0 -0
|
@@ -44,7 +44,15 @@ module Datadog
|
|
|
44
44
|
|
|
45
45
|
tracestate, sampling_priority, origin, tags, unknown_fields = extract_tracestate(fetcher[@tracestate_key])
|
|
46
46
|
|
|
47
|
-
sampling_priority = parse_priority_sampling(sampled, sampling_priority)
|
|
47
|
+
sampling_priority = parse_priority_sampling(sampled, sampling_priority) do |decision|
|
|
48
|
+
case decision
|
|
49
|
+
when String
|
|
50
|
+
tags ||= {}
|
|
51
|
+
tags[Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER] = decision
|
|
52
|
+
when :drop
|
|
53
|
+
tags.delete(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER) if tags
|
|
54
|
+
end
|
|
55
|
+
end
|
|
48
56
|
|
|
49
57
|
TraceDigest.new(
|
|
50
58
|
span_id: parent_id,
|
|
@@ -160,8 +168,10 @@ module Datadog
|
|
|
160
168
|
tracestate.chop! # Removes trailing `;` from Datadog trace state string.
|
|
161
169
|
|
|
162
170
|
if digest.trace_state
|
|
171
|
+
trace_state = digest.trace_state.strip
|
|
172
|
+
|
|
163
173
|
# Delete existing `dd=` tracestate fields, if present.
|
|
164
|
-
vendors = split_tracestate(
|
|
174
|
+
vendors = split_tracestate(trace_state)
|
|
165
175
|
vendors.reject! { |v| v.start_with?('dd=') }
|
|
166
176
|
end
|
|
167
177
|
|
|
@@ -179,13 +189,21 @@ module Datadog
|
|
|
179
189
|
end
|
|
180
190
|
|
|
181
191
|
# If any characters in <origin_value> are invalid, replace each invalid character with 0x5F (underscore).
|
|
182
|
-
# Invalid characters are: characters outside the ASCII range 0x20 to 0x7E,
|
|
192
|
+
# Invalid characters are: characters outside the ASCII range 0x20 to 0x7E,
|
|
193
|
+
# 0x2C (comma), 0x3B (semi-colon), and 0x7E (tilde).
|
|
194
|
+
# Then, remap 0x3D (equals) to 0x7E (tilde)
|
|
183
195
|
def serialize_origin(value)
|
|
184
196
|
# DEV: It's unlikely that characters will be out of range, as they mostly
|
|
185
197
|
# DEV: come from Datadog-controlled sources.
|
|
186
198
|
# DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
|
|
187
|
-
if INVALID_ORIGIN_CHARS.match?(value)
|
|
188
|
-
|
|
199
|
+
value = if INVALID_ORIGIN_CHARS.match?(value)
|
|
200
|
+
value.gsub(INVALID_ORIGIN_CHARS, '_')
|
|
201
|
+
else
|
|
202
|
+
value
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
if REMAP_ORIGIN_CHARS.match?(value)
|
|
206
|
+
value.gsub(REMAP_ORIGIN_CHARS, '~')
|
|
189
207
|
else
|
|
190
208
|
value
|
|
191
209
|
end
|
|
@@ -245,13 +263,15 @@ module Datadog
|
|
|
245
263
|
|
|
246
264
|
version, trace_id, parent_id, trace_flags, extra = traceparent.strip.split('-')
|
|
247
265
|
|
|
266
|
+
return if version.size != 2 || version[0] < '0' || version[0] > 'f' || version[1] < '0' || version[1] > 'f'
|
|
267
|
+
|
|
248
268
|
return if version == INVALID_VERSION
|
|
249
269
|
|
|
250
270
|
# Extra fields are not allowed in version 00, but we have to be lenient for future versions.
|
|
251
271
|
return if version == SPEC_VERSION && extra
|
|
252
272
|
|
|
253
273
|
# Invalid field sizes
|
|
254
|
-
return if
|
|
274
|
+
return if trace_id.size != 32 || parent_id.size != 16 || trace_flags.size != 2
|
|
255
275
|
|
|
256
276
|
[Integer(trace_id, 16), Integer(parent_id, 16), Integer(trace_flags, 16)]
|
|
257
277
|
rescue ArgumentError # Conversion to integer failed
|
|
@@ -324,20 +344,31 @@ module Datadog
|
|
|
324
344
|
|
|
325
345
|
# If `sampled` and `sampling_priority` disagree, `sampled` overrides the decision.
|
|
326
346
|
# @return [Integer] one of the {Datadog::Tracing::Sampling::Ext::Priority} values
|
|
347
|
+
# @yieldparam the new decision maker (either :drop or a new decision maker String value).
|
|
327
348
|
def parse_priority_sampling(sampled, sampling_priority)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
349
|
+
if sampled == 1
|
|
350
|
+
if sampling_priority && Tracing::Sampling::PrioritySampler.sampled?(sampling_priority)
|
|
351
|
+
# Both sampling fields agree.
|
|
352
|
+
sampling_priority
|
|
353
|
+
else
|
|
354
|
+
# Sampling fields disagree.
|
|
355
|
+
# Let's force the trace to be kept, while also updating the decision maker to ourselves.
|
|
356
|
+
yield Tracing::Sampling::Ext::Decision::DEFAULT
|
|
357
|
+
sampled
|
|
358
|
+
end
|
|
359
|
+
elsif sampling_priority && !Tracing::Sampling::PrioritySampler.sampled?(sampling_priority)
|
|
360
|
+
sampling_priority
|
|
361
|
+
# Both sampling fields agree.
|
|
362
|
+
else
|
|
363
|
+
# Sampling fields disagree.
|
|
364
|
+
# Let's drop the trace and remove the sampling decision tag, as dropped spans don't carry sampling decision.
|
|
365
|
+
yield :drop
|
|
366
|
+
sampled
|
|
334
367
|
end
|
|
335
|
-
|
|
336
|
-
sampled # Sampled flag trumps `sampling_priority` on conflict
|
|
337
368
|
end
|
|
338
369
|
|
|
339
370
|
def split_tracestate(tracestate)
|
|
340
|
-
tracestate.split(/[ \t]
|
|
371
|
+
tracestate.split(/[ \t]*+,[ \t]*+/)[0..31]
|
|
341
372
|
end
|
|
342
373
|
|
|
343
374
|
# Version 0xFF is invalid as per spec
|
|
@@ -361,10 +392,14 @@ module Datadog
|
|
|
361
392
|
private_constant :TRACESTATE_VALUE_SIZE_LIMIT
|
|
362
393
|
|
|
363
394
|
# Replace all characters with `_`, except ASCII characters 0x20-0x7E.
|
|
364
|
-
# Additionally, `,`, ';', and
|
|
365
|
-
INVALID_ORIGIN_CHARS = /[\u0000-\u0019
|
|
395
|
+
# Additionally, `,`, ';', and `~` must also be replaced by `_`.
|
|
396
|
+
INVALID_ORIGIN_CHARS = /[\u0000-\u0019,;~\u007F-\u{10FFFF}]/.freeze
|
|
366
397
|
private_constant :INVALID_ORIGIN_CHARS
|
|
367
398
|
|
|
399
|
+
# Additionally, remap `=` to `~`
|
|
400
|
+
REMAP_ORIGIN_CHARS = /=/.freeze
|
|
401
|
+
private_constant :REMAP_ORIGIN_CHARS
|
|
402
|
+
|
|
368
403
|
# Replace all characters with `_`, except ASCII characters 0x21-0x7E.
|
|
369
404
|
# Additionally, `,` and `=` must also be replaced by `_`.
|
|
370
405
|
INVALID_TAG_KEY_CHARS = /[\u0000-\u0020,=\u007F-\u{10FFFF}]/.freeze
|
|
@@ -23,6 +23,10 @@ module Datadog
|
|
|
23
23
|
# Set this tag to `1.0` if the span is a Service Entry span.
|
|
24
24
|
TAG_TOP_LEVEL = '_dd.top_level'
|
|
25
25
|
|
|
26
|
+
# Set to `1.0` if profiling is enabled together with tracing, and `0.0` otherwise
|
|
27
|
+
# See Datadog-internal "RFC: Identifying which spans have profiling enabled " for details
|
|
28
|
+
TAG_PROFILING_ENABLED = '_dd.profiling.enabled'
|
|
29
|
+
|
|
26
30
|
# Defines constants for trace analytics
|
|
27
31
|
# @public_api
|
|
28
32
|
module Analytics
|
|
@@ -90,7 +94,10 @@ module Datadog
|
|
|
90
94
|
INVALID_TAG_CHARACTERS = %r{[^a-z0-9_\-:./]}.freeze
|
|
91
95
|
|
|
92
96
|
# Normalizes an HTTP header string into a valid tag string.
|
|
93
|
-
|
|
97
|
+
#
|
|
98
|
+
# By default, tags cannot create nested span tag levels:
|
|
99
|
+
# `allow_nested` allows you to override this behavior.
|
|
100
|
+
def to_tag(name, allow_nested: false)
|
|
94
101
|
# Tag normalization based on: https://docs.datadoghq.com/getting_started/tagging/#defining-tags.
|
|
95
102
|
#
|
|
96
103
|
# Only the following characters are accepted.
|
|
@@ -109,7 +116,7 @@ module Datadog
|
|
|
109
116
|
# Additional HTTP header normalization.
|
|
110
117
|
#
|
|
111
118
|
# Periods are replaced with an underscore.
|
|
112
|
-
tag.tr!('.', '_')
|
|
119
|
+
tag.tr!('.', '_') unless allow_nested
|
|
113
120
|
tag
|
|
114
121
|
end
|
|
115
122
|
end
|
|
@@ -178,10 +185,6 @@ module Datadog
|
|
|
178
185
|
end
|
|
179
186
|
|
|
180
187
|
# @public_api
|
|
181
|
-
module SpanAttributeSchema
|
|
182
|
-
# current span attribute schema version
|
|
183
|
-
TAG_SCHEMA_VERSION = '_dd.trace_span_attribute_schema'
|
|
184
|
-
end
|
|
185
188
|
end
|
|
186
189
|
end
|
|
187
190
|
end
|
|
@@ -59,8 +59,8 @@ module Datadog
|
|
|
59
59
|
# A valid example is:
|
|
60
60
|
#
|
|
61
61
|
# span.set_tags({ "http.method" => "GET", "user.id" => "234" })
|
|
62
|
-
def set_tags(
|
|
63
|
-
|
|
62
|
+
def set_tags(hash)
|
|
63
|
+
hash.each { |k, v| set_tag(k, v) }
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Returns true if the provided `tag` was set to a non-nil value.
|
|
@@ -111,7 +111,7 @@ module Datadog
|
|
|
111
111
|
# Returns a copy of all metadata.
|
|
112
112
|
# Keys for `@meta` and `@metrics` don't collide, by construction.
|
|
113
113
|
def tags
|
|
114
|
-
|
|
114
|
+
meta.merge(metrics)
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
protected
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../core/remote/dispatcher'
|
|
4
|
+
require_relative 'configuration/dynamic'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module Tracing
|
|
8
|
+
# Remote configuration declaration
|
|
9
|
+
module Remote
|
|
10
|
+
class ReadError < StandardError; end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
PRODUCT = 'APM_TRACING'
|
|
14
|
+
|
|
15
|
+
def products
|
|
16
|
+
[PRODUCT]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def capabilities
|
|
20
|
+
[] # No capabilities advertised
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def process_config(config, content)
|
|
24
|
+
lib_config = config['lib_config']
|
|
25
|
+
|
|
26
|
+
env_vars = Datadog::Tracing::Configuration::Dynamic::OPTIONS.map do |name, env_var, option|
|
|
27
|
+
value = lib_config[name]
|
|
28
|
+
|
|
29
|
+
# Guard for RBS/Steep
|
|
30
|
+
raise "option is a #{option.class}, expected Option" unless option.is_a?(Configuration::Dynamic::Option)
|
|
31
|
+
|
|
32
|
+
option.call(value)
|
|
33
|
+
|
|
34
|
+
[env_var, value]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
content.applied
|
|
38
|
+
|
|
39
|
+
Datadog.send(:components).telemetry.client_configuration_change!(env_vars)
|
|
40
|
+
rescue => e
|
|
41
|
+
content.errored("#{e.class.name} #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def receivers
|
|
45
|
+
receiver do |repository, _changes|
|
|
46
|
+
# DEV: Filter our by product. Given it will be very common
|
|
47
|
+
# DEV: we can filter this out before we receive the data in this method.
|
|
48
|
+
# DEV: Apply this refactor to AppSec as well if implemented.
|
|
49
|
+
repository.contents.map do |content|
|
|
50
|
+
case content.path.product
|
|
51
|
+
when PRODUCT
|
|
52
|
+
config = parse_content(content)
|
|
53
|
+
process_config(config, content)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def receiver(products = [PRODUCT], &block)
|
|
60
|
+
matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
|
|
61
|
+
[Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def parse_content(content)
|
|
67
|
+
data = content.data.read
|
|
68
|
+
|
|
69
|
+
content.data.rewind
|
|
70
|
+
|
|
71
|
+
raise ReadError, 'EOF reached' if data.nil?
|
|
72
|
+
|
|
73
|
+
JSON.parse(data)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -29,20 +29,40 @@ module Datadog
|
|
|
29
29
|
end
|
|
30
30
|
end.new
|
|
31
31
|
|
|
32
|
-
attr_reader :name, :service
|
|
32
|
+
attr_reader :name, :service, :resource, :tags
|
|
33
33
|
|
|
34
34
|
# @param name [String,Regexp,Proc] Matcher for case equality (===) with the trace name,
|
|
35
35
|
# defaults to always match
|
|
36
36
|
# @param service [String,Regexp,Proc] Matcher for case equality (===) with the service name,
|
|
37
37
|
# defaults to always match
|
|
38
|
-
|
|
38
|
+
# @param resource [String,Regexp,Proc] Matcher for case equality (===) with the resource name,
|
|
39
|
+
# defaults to always match
|
|
40
|
+
def initialize(name: MATCH_ALL, service: MATCH_ALL, resource: MATCH_ALL, tags: {})
|
|
39
41
|
super()
|
|
40
42
|
@name = name
|
|
41
43
|
@service = service
|
|
44
|
+
@resource = resource
|
|
45
|
+
@tags = tags
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def match?(trace)
|
|
45
|
-
name === trace.name && service === trace.service
|
|
49
|
+
name === trace.name && service === trace.service && resource === trace.resource && tags_match?(trace)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Match against the trace tags and metrics.
|
|
55
|
+
def tags_match?(trace)
|
|
56
|
+
@tags.all? do |name, matcher|
|
|
57
|
+
tag = trace.get_tag(name)
|
|
58
|
+
|
|
59
|
+
# Format metrics as strings, to allow for partial number matching (/4.*/ matching '400', '404', etc.).
|
|
60
|
+
# Because metrics are floats, we use the '%g' format specifier to avoid trailing zeros, which
|
|
61
|
+
# can affect exact string matching (e.g. '400' matching '400.0').
|
|
62
|
+
tag = format('%g', tag) if tag.is_a?(Numeric)
|
|
63
|
+
|
|
64
|
+
matcher === tag
|
|
65
|
+
end
|
|
46
66
|
end
|
|
47
67
|
end
|
|
48
68
|
|
|
@@ -51,8 +51,13 @@ module Datadog
|
|
|
51
51
|
# @param name [String,Regexp,Proc] Matcher for case equality (===) with the trace name, defaults to always match
|
|
52
52
|
# @param service [String,Regexp,Proc] Matcher for case equality (===) with the service name,
|
|
53
53
|
# defaults to always match
|
|
54
|
+
# @param resource [String,Regexp,Proc] Matcher for case equality (===) with the resource name,
|
|
55
|
+
# defaults to always match
|
|
54
56
|
# @param sample_rate [Float] Sampling rate between +[0,1]+
|
|
55
|
-
def initialize(
|
|
57
|
+
def initialize(
|
|
58
|
+
name: SimpleMatcher::MATCH_ALL, service: SimpleMatcher::MATCH_ALL,
|
|
59
|
+
resource: SimpleMatcher::MATCH_ALL, tags: {}, sample_rate: 1.0
|
|
60
|
+
)
|
|
56
61
|
# We want to allow 0.0 to drop all traces, but {Datadog::Tracing::Sampling::RateSampler}
|
|
57
62
|
# considers 0.0 an invalid rate and falls back to 100% sampling.
|
|
58
63
|
#
|
|
@@ -64,7 +69,7 @@ module Datadog
|
|
|
64
69
|
sampler = RateSampler.new
|
|
65
70
|
sampler.sample_rate = sample_rate
|
|
66
71
|
|
|
67
|
-
super(SimpleMatcher.new(name: name, service: service), sampler)
|
|
72
|
+
super(SimpleMatcher.new(name: name, service: service, resource: resource, tags: tags), sampler)
|
|
68
73
|
end
|
|
69
74
|
end
|
|
70
75
|
end
|
|
@@ -48,6 +48,37 @@ module Datadog
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def self.parse(rules, rate_limit, default_sample_rate)
|
|
52
|
+
parsed_rules = JSON.parse(rules).map do |rule|
|
|
53
|
+
sample_rate = rule['sample_rate']
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
sample_rate = Float(sample_rate)
|
|
57
|
+
rescue
|
|
58
|
+
raise "Rule '#{rule.inspect}' does not contain a float property `sample_rate`"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
kwargs = {
|
|
62
|
+
name: rule['name'],
|
|
63
|
+
service: rule['service'],
|
|
64
|
+
resource: rule['resource'],
|
|
65
|
+
tags: rule['tags'],
|
|
66
|
+
sample_rate: sample_rate,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Core::BackportFrom24.hash_compact!(kwargs)
|
|
70
|
+
|
|
71
|
+
SimpleRule.new(**kwargs)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
new(parsed_rules, rate_limit: rate_limit, default_sample_rate: default_sample_rate)
|
|
75
|
+
rescue => e
|
|
76
|
+
Datadog.logger.error do
|
|
77
|
+
"Could not parse trace sampling rules '#{rules}': #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
|
|
78
|
+
end
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
51
82
|
# /RuleSampler's components (it's rate limiter, for example) are
|
|
52
83
|
# not be guaranteed to be size-effect free.
|
|
53
84
|
# It is not possible to guarantee that a call to {#sample?} will
|
|
@@ -3,6 +3,7 @@ require 'time'
|
|
|
3
3
|
require_relative '../core/environment/identity'
|
|
4
4
|
require_relative '../core/utils'
|
|
5
5
|
require_relative '../core/utils/time'
|
|
6
|
+
require_relative '../core/utils/safe_dup'
|
|
6
7
|
|
|
7
8
|
require_relative 'event'
|
|
8
9
|
require_relative 'metadata'
|
|
@@ -434,19 +435,6 @@ module Datadog
|
|
|
434
435
|
:parent,
|
|
435
436
|
:span
|
|
436
437
|
|
|
437
|
-
if RUBY_VERSION < '2.2' # nil.dup only fails in Ruby 2.1
|
|
438
|
-
# Ensures #initialize can call nil.dup safely
|
|
439
|
-
module RefineNil
|
|
440
|
-
refine NilClass do
|
|
441
|
-
def dup
|
|
442
|
-
self
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
using RefineNil
|
|
448
|
-
end
|
|
449
|
-
|
|
450
438
|
# Create a Span from the operation which represents
|
|
451
439
|
# the finalized measurement. We #dup here to prevent
|
|
452
440
|
# mutation by reference; when this span is returned,
|
|
@@ -457,8 +445,8 @@ module Datadog
|
|
|
457
445
|
duration: duration,
|
|
458
446
|
end_time: @end_time,
|
|
459
447
|
id: @id,
|
|
460
|
-
meta: meta
|
|
461
|
-
metrics: metrics
|
|
448
|
+
meta: Core::Utils::SafeDup.frozen_or_dup(meta),
|
|
449
|
+
metrics: Core::Utils::SafeDup.frozen_or_dup(metrics),
|
|
462
450
|
parent_id: @parent_id,
|
|
463
451
|
resource: @resource,
|
|
464
452
|
service: @service,
|
|
@@ -4,7 +4,7 @@ require_relative 'pipeline'
|
|
|
4
4
|
require_relative 'runtime/metrics'
|
|
5
5
|
require_relative 'writer'
|
|
6
6
|
|
|
7
|
-
require_relative '
|
|
7
|
+
require_relative 'transport/http'
|
|
8
8
|
|
|
9
9
|
module Datadog
|
|
10
10
|
module Tracing
|
|
@@ -20,10 +20,10 @@ module Datadog
|
|
|
20
20
|
:events,
|
|
21
21
|
:transport
|
|
22
22
|
|
|
23
|
-
# @param [Datadog::Transport::Traces::Transport] transport a custom transport instance.
|
|
23
|
+
# @param [Datadog::Tracing::Transport::Traces::Transport] transport a custom transport instance.
|
|
24
24
|
# If provided, overrides `transport_options` and `agent_settings`.
|
|
25
25
|
# @param [Hash<Symbol,Object>] transport_options options for the default transport instance.
|
|
26
|
-
# @param [Datadog::
|
|
26
|
+
# @param [Datadog::Tracing::Configuration::AgentSettingsResolver::AgentSettings] agent_settings agent options for
|
|
27
27
|
# the default transport instance.
|
|
28
28
|
def initialize(transport: nil, transport_options: {}, agent_settings: nil)
|
|
29
29
|
@transport = transport || begin
|
|
@@ -141,6 +141,37 @@ module Datadog
|
|
|
141
141
|
|
|
142
142
|
freeze
|
|
143
143
|
end
|
|
144
|
+
|
|
145
|
+
# Creates a copy of this object, modifying the provided fields.
|
|
146
|
+
# @param field_value_pairs [Hash<String>] the fields to be overwritten
|
|
147
|
+
# @return [TraceDigest] returns a copy of this object with the `field_value_pairs` modified
|
|
148
|
+
def merge(field_value_pairs)
|
|
149
|
+
# DEV: Because we want to sometimes freeze the values provided to `TraceDigest`, it's best
|
|
150
|
+
# DEV: to let `#initialize` decide how to handle each field, instead of duplicating that logic here.
|
|
151
|
+
TraceDigest.new(
|
|
152
|
+
**{
|
|
153
|
+
span_id: span_id,
|
|
154
|
+
span_name: span_name,
|
|
155
|
+
span_resource: span_resource,
|
|
156
|
+
span_service: span_service,
|
|
157
|
+
span_type: span_type,
|
|
158
|
+
trace_distributed_tags: trace_distributed_tags,
|
|
159
|
+
trace_hostname: trace_hostname,
|
|
160
|
+
trace_id: trace_id,
|
|
161
|
+
trace_name: trace_name,
|
|
162
|
+
trace_origin: trace_origin,
|
|
163
|
+
trace_process_id: trace_process_id,
|
|
164
|
+
trace_resource: trace_resource,
|
|
165
|
+
trace_runtime_id: trace_runtime_id,
|
|
166
|
+
trace_sampling_priority: trace_sampling_priority,
|
|
167
|
+
trace_service: trace_service,
|
|
168
|
+
trace_distributed_id: trace_distributed_id,
|
|
169
|
+
trace_flags: trace_flags,
|
|
170
|
+
trace_state: trace_state,
|
|
171
|
+
trace_state_unknown_fields: trace_state_unknown_fields,
|
|
172
|
+
}.merge!(field_value_pairs)
|
|
173
|
+
)
|
|
174
|
+
end
|
|
144
175
|
end
|
|
145
176
|
end
|
|
146
177
|
end
|
|
@@ -40,7 +40,9 @@ module Datadog
|
|
|
40
40
|
:active_span,
|
|
41
41
|
:id,
|
|
42
42
|
:max_length,
|
|
43
|
-
:parent_span_id
|
|
43
|
+
:parent_span_id,
|
|
44
|
+
:trace_state,
|
|
45
|
+
:trace_state_unknown_fields
|
|
44
46
|
|
|
45
47
|
attr_writer \
|
|
46
48
|
:name,
|
|
@@ -64,8 +66,11 @@ module Datadog
|
|
|
64
66
|
sampled: nil,
|
|
65
67
|
sampling_priority: nil,
|
|
66
68
|
service: nil,
|
|
69
|
+
profiling_enabled: nil,
|
|
67
70
|
tags: nil,
|
|
68
|
-
metrics: nil
|
|
71
|
+
metrics: nil,
|
|
72
|
+
trace_state: nil,
|
|
73
|
+
trace_state_unknown_fields: nil
|
|
69
74
|
)
|
|
70
75
|
# Attributes
|
|
71
76
|
@id = id || Tracing::Utils::TraceId.next_id
|
|
@@ -84,6 +89,9 @@ module Datadog
|
|
|
84
89
|
@sample_rate = sample_rate
|
|
85
90
|
@sampling_priority = sampling_priority
|
|
86
91
|
@service = service
|
|
92
|
+
@profiling_enabled = profiling_enabled
|
|
93
|
+
@trace_state = trace_state
|
|
94
|
+
@trace_state_unknown_fields = trace_state_unknown_fields
|
|
87
95
|
|
|
88
96
|
# Generic tags
|
|
89
97
|
set_tags(tags) if tags
|
|
@@ -129,13 +137,12 @@ module Datadog
|
|
|
129
137
|
end
|
|
130
138
|
|
|
131
139
|
def keep!
|
|
132
|
-
self.sampled = true
|
|
133
140
|
self.sampling_priority = Sampling::Ext::Priority::USER_KEEP
|
|
134
141
|
set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, Tracing::Sampling::Ext::Decision::MANUAL)
|
|
142
|
+
self.sampled = true # Just in case the in-app sampler had decided to drop this span, we revert that decision.
|
|
135
143
|
end
|
|
136
144
|
|
|
137
145
|
def reject!
|
|
138
|
-
self.sampled = false
|
|
139
146
|
self.sampling_priority = Sampling::Ext::Priority::USER_REJECT
|
|
140
147
|
set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, Tracing::Sampling::Ext::Decision::MANUAL)
|
|
141
148
|
end
|
|
@@ -288,6 +295,8 @@ module Datadog
|
|
|
288
295
|
trace_runtime_id: Core::Environment::Identity.id,
|
|
289
296
|
trace_sampling_priority: @sampling_priority,
|
|
290
297
|
trace_service: service,
|
|
298
|
+
trace_state: @trace_state,
|
|
299
|
+
trace_state_unknown_fields: @trace_state_unknown_fields,
|
|
291
300
|
).freeze
|
|
292
301
|
end
|
|
293
302
|
|
|
@@ -310,6 +319,8 @@ module Datadog
|
|
|
310
319
|
sampled: @sampled,
|
|
311
320
|
sampling_priority: @sampling_priority,
|
|
312
321
|
service: (service && service.dup),
|
|
322
|
+
trace_state: (@trace_state && @trace_state.dup),
|
|
323
|
+
trace_state_unknown_fields: (@trace_state_unknown_fields && @trace_state_unknown_fields.dup),
|
|
313
324
|
tags: meta.dup,
|
|
314
325
|
metrics: metrics.dup
|
|
315
326
|
)
|
|
@@ -450,7 +461,8 @@ module Datadog
|
|
|
450
461
|
service: service,
|
|
451
462
|
tags: meta,
|
|
452
463
|
metrics: metrics,
|
|
453
|
-
root_span_id: !partial ? root_span && root_span.id : nil
|
|
464
|
+
root_span_id: !partial ? root_span && root_span.id : nil,
|
|
465
|
+
profiling_enabled: @profiling_enabled,
|
|
454
466
|
)
|
|
455
467
|
end
|
|
456
468
|
|
|
@@ -31,7 +31,8 @@ module Datadog
|
|
|
31
31
|
:sample_rate,
|
|
32
32
|
:sampling_decision_maker,
|
|
33
33
|
:sampling_priority,
|
|
34
|
-
:service
|
|
34
|
+
:service,
|
|
35
|
+
:profiling_enabled
|
|
35
36
|
|
|
36
37
|
# rubocop:disable Metrics/CyclomaticComplexity
|
|
37
38
|
# rubocop:disable Metrics/PerceivedComplexity
|
|
@@ -54,7 +55,8 @@ module Datadog
|
|
|
54
55
|
sampling_priority: nil,
|
|
55
56
|
service: nil,
|
|
56
57
|
tags: nil,
|
|
57
|
-
metrics: nil
|
|
58
|
+
metrics: nil,
|
|
59
|
+
profiling_enabled: nil
|
|
58
60
|
)
|
|
59
61
|
@id = id
|
|
60
62
|
@root_span_id = root_span_id
|
|
@@ -80,6 +82,7 @@ module Datadog
|
|
|
80
82
|
@sampling_decision_maker = sampling_decision_maker_tag
|
|
81
83
|
@sampling_priority = sampling_priority || sampling_priority_tag
|
|
82
84
|
@service = Core::Utils::SafeDup.frozen_or_dup(service || service_tag)
|
|
85
|
+
@profiling_enabled = profiling_enabled
|
|
83
86
|
end
|
|
84
87
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
85
88
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
@@ -320,16 +320,20 @@ module Datadog
|
|
|
320
320
|
if digest
|
|
321
321
|
TraceOperation.new(
|
|
322
322
|
hostname: hostname,
|
|
323
|
+
profiling_enabled: profiling_enabled,
|
|
323
324
|
id: digest.trace_id,
|
|
324
325
|
origin: digest.trace_origin,
|
|
325
326
|
parent_span_id: digest.span_id,
|
|
326
327
|
sampling_priority: digest.trace_sampling_priority,
|
|
327
328
|
# Distributed tags are just regular trace tags with special meaning to Datadog
|
|
328
329
|
tags: digest.trace_distributed_tags,
|
|
330
|
+
trace_state: digest.trace_state,
|
|
331
|
+
trace_state_unknown_fields: digest.trace_state_unknown_fields,
|
|
329
332
|
)
|
|
330
333
|
else
|
|
331
334
|
TraceOperation.new(
|
|
332
|
-
hostname: hostname
|
|
335
|
+
hostname: hostname,
|
|
336
|
+
profiling_enabled: profiling_enabled,
|
|
333
337
|
)
|
|
334
338
|
end
|
|
335
339
|
end
|
|
@@ -349,6 +353,8 @@ module Datadog
|
|
|
349
353
|
end
|
|
350
354
|
end
|
|
351
355
|
|
|
356
|
+
# Creates a new TraceOperation, with events bounds to this Tracer instance.
|
|
357
|
+
# @return [TraceOperation]
|
|
352
358
|
def start_trace(continue_from: nil)
|
|
353
359
|
# Build a new trace using digest if provided.
|
|
354
360
|
trace = build_trace(continue_from)
|
|
@@ -525,6 +531,11 @@ module Datadog
|
|
|
525
531
|
span
|
|
526
532
|
end
|
|
527
533
|
end
|
|
534
|
+
|
|
535
|
+
def profiling_enabled
|
|
536
|
+
@profiling_enabled ||=
|
|
537
|
+
!!(defined?(Datadog::Profiling) && Datadog::Profiling.respond_to?(:enabled?) && Datadog::Profiling.enabled?)
|
|
538
|
+
end
|
|
528
539
|
end
|
|
529
540
|
end
|
|
530
541
|
end
|