ddtrace 1.5.1 → 1.6.0

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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
  4. data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
  5. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
  6. data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
  7. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
  8. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
  9. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
  10. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
  11. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
  12. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
  14. data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
  15. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
  16. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -2
  17. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
  19. data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
  20. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
  21. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
  24. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +44 -18
  25. data/lib/datadog/appsec/event.rb +8 -4
  26. data/lib/datadog/core/configuration/components.rb +20 -14
  27. data/lib/datadog/core/configuration/settings.rb +59 -7
  28. data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
  29. data/lib/datadog/core/utils/compression.rb +5 -1
  30. data/lib/datadog/core.rb +0 -54
  31. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
  32. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
  33. data/lib/datadog/profiling/exporter.rb +2 -4
  34. data/lib/datadog/profiling/http_transport.rb +1 -1
  35. data/lib/datadog/tracing/client_ip.rb +11 -0
  36. data/lib/datadog/tracing/configuration/ext.rb +3 -1
  37. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
  38. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  39. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
  40. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
  41. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
  42. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -0
  43. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
  44. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
  45. data/lib/datadog/tracing/contrib/ext.rb +6 -0
  46. data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -0
  47. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
  48. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
  49. data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
  50. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
  51. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
  52. data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
  53. data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
  54. data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
  55. data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
  56. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
  57. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
  58. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
  59. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
  60. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
  61. data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
  62. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
  63. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
  64. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  65. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
  66. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
  67. data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
  68. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +34 -18
  69. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
  70. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
  71. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
  72. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
  73. data/lib/datadog/tracing/contrib/rack/middlewares.rb +15 -7
  74. data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
  75. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
  76. data/lib/datadog/tracing/contrib/redis/patcher.rb +41 -0
  77. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
  78. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
  79. data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
  80. data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
  81. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
  82. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
  83. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
  84. data/lib/datadog/tracing/contrib.rb +1 -0
  85. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
  86. data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
  87. data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
  88. data/lib/datadog/tracing/flush.rb +1 -1
  89. data/lib/datadog/tracing/metadata/ext.rb +8 -0
  90. data/lib/datadog/tracing/propagation/http.rb +9 -1
  91. data/lib/datadog/tracing/sampling/ext.rb +31 -0
  92. data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
  93. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
  94. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
  95. data/lib/datadog/tracing/sampling/rate_sampler.rb +10 -3
  96. data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
  97. data/lib/datadog/tracing/sampling/span/ext.rb +0 -4
  98. data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
  99. data/lib/datadog/tracing/sampling/span/sampler.rb +14 -3
  100. data/lib/datadog/tracing/trace_digest.rb +3 -0
  101. data/lib/datadog/tracing/trace_operation.rb +10 -0
  102. data/lib/datadog/tracing/trace_segment.rb +6 -0
  103. data/lib/datadog/tracing/tracer.rb +3 -1
  104. data/lib/datadog/tracing/writer.rb +7 -0
  105. data/lib/ddtrace/transport/trace_formatter.rb +7 -0
  106. data/lib/ddtrace/transport/traces.rb +1 -1
  107. data/lib/ddtrace/version.rb +2 -2
  108. metadata +18 -14
  109. data/lib/datadog/profiling/old_ext.rb +0 -42
  110. data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
  111. data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
  112. data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
  113. data/lib/datadog/profiling/transport/http/api.rb +0 -45
  114. data/lib/datadog/profiling/transport/http/builder.rb +0 -30
  115. data/lib/datadog/profiling/transport/http/client.rb +0 -37
  116. data/lib/datadog/profiling/transport/http/response.rb +0 -21
  117. data/lib/datadog/profiling/transport/http.rb +0 -118
@@ -51,6 +51,8 @@ module Datadog
51
51
  private
52
52
 
53
53
  def annotate_span_with_request!(span, req, req_options)
54
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
55
+
54
56
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
55
57
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
56
58
 
@@ -51,6 +51,8 @@ module Datadog
51
51
  private
52
52
 
53
53
  def annotate_span_with_request!(span, req, req_options)
54
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
55
+
54
56
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
55
57
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
56
58
 
@@ -20,6 +20,13 @@ module Datadog
20
20
  TAG_ROWS = 'mongodb.rows'.freeze
21
21
  TAG_COMPONENT = 'mongodb'.freeze
22
22
  TAG_OPERATION_COMMAND = 'command'.freeze
23
+ TAG_SYSTEM = 'mongodb'.freeze
24
+
25
+ # Temporary namespace to accommodate unified tags which has naming collision, before
26
+ # making breaking changes
27
+ module DB
28
+ TAG_COLLECTION = 'db.mongodb.collection'.freeze
29
+ end
23
30
  end
24
31
  end
25
32
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../analytics'
4
4
  require_relative 'ext'
5
+ require_relative '../ext'
5
6
  require_relative 'parsers'
6
7
  require_relative '../../metadata/ext'
7
8
 
@@ -30,6 +31,8 @@ module Datadog
30
31
  query = MongoDB.query_builder(event.command_name, event.database_name, event.command)
31
32
  serialized_query = query.to_s
32
33
 
34
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
35
+
33
36
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
34
37
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_COMMAND)
35
38
 
@@ -44,6 +47,7 @@ module Datadog
44
47
  # since it has been quantized and reduced
45
48
  span.set_tag(Ext::TAG_DB, query['database'])
46
49
  span.set_tag(Ext::TAG_COLLECTION, query['collection'])
50
+ span.set_tag(Ext::DB::TAG_COLLECTION, query['collection'])
47
51
  span.set_tag(Ext::TAG_OPERATION, query['operation'])
48
52
  span.set_tag(Ext::TAG_QUERY, serialized_query)
49
53
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, event.address.host)
@@ -3,6 +3,8 @@
3
3
  require_relative '../../configuration/settings'
4
4
  require_relative '../ext'
5
5
 
6
+ require_relative '../../propagation/sql_comment'
7
+
6
8
  module Datadog
7
9
  module Tracing
8
10
  module Contrib
@@ -27,6 +29,16 @@ module Datadog
27
29
  end
28
30
 
29
31
  option :service_name, default: Ext::DEFAULT_PEER_SERVICE_NAME
32
+
33
+ option :comment_propagation do |o|
34
+ o.default do
35
+ ENV.fetch(
36
+ Contrib::Propagation::SqlComment::Ext::ENV_DBM_PROPAGATION_MODE,
37
+ Contrib::Propagation::SqlComment::Ext::DISABLED
38
+ )
39
+ end
40
+ o.lazy
41
+ end
30
42
  end
31
43
  end
32
44
  end
@@ -15,6 +15,7 @@ module Datadog
15
15
  TAG_DB_NAME = 'mysql2.db.name'.freeze
16
16
  TAG_COMPONENT = 'mysql2'.freeze
17
17
  TAG_OPERATION_QUERY = 'query'.freeze
18
+ TAG_SYSTEM = 'mysql'.freeze
18
19
  end
19
20
  end
20
21
  end
@@ -3,6 +3,9 @@
3
3
  require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative 'ext'
6
+ require_relative '../ext'
7
+ require_relative '../propagation/sql_comment'
8
+ require_relative '../propagation/sql_comment/mode'
6
9
 
7
10
  module Datadog
8
11
  module Tracing
@@ -23,6 +26,9 @@ module Datadog
23
26
  span.resource = sql
24
27
  span.span_type = Tracing::Metadata::Ext::SQL::TYPE
25
28
 
29
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
30
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
31
+
26
32
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
27
33
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_QUERY)
28
34
 
@@ -36,6 +42,12 @@ module Datadog
36
42
  span.set_tag(Ext::TAG_DB_NAME, query_options[:database])
37
43
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, query_options[:host])
38
44
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, query_options[:port])
45
+
46
+ propagation_mode = Contrib::Propagation::SqlComment::Mode.new(comment_propagation)
47
+
48
+ Contrib::Propagation::SqlComment.annotate!(span, propagation_mode)
49
+ sql = Contrib::Propagation::SqlComment.prepend_comment(sql, span, propagation_mode)
50
+
39
51
  super(sql, options)
40
52
  end
41
53
  end
@@ -53,6 +65,10 @@ module Datadog
53
65
  def analytics_sample_rate
54
66
  datadog_configuration[:analytics_sample_rate]
55
67
  end
68
+
69
+ def comment_propagation
70
+ datadog_configuration[:comment_propagation]
71
+ end
56
72
  end
57
73
  end
58
74
  end
@@ -3,6 +3,8 @@
3
3
  require_relative '../../configuration/settings'
4
4
  require_relative '../ext'
5
5
 
6
+ require_relative '../../propagation/sql_comment/ext'
7
+
6
8
  module Datadog
7
9
  module Tracing
8
10
  module Contrib
@@ -27,6 +29,16 @@ module Datadog
27
29
  end
28
30
 
29
31
  option :service_name, default: Ext::DEFAULT_PEER_SERVICE_NAME
32
+
33
+ option :comment_propagation do |o|
34
+ o.default do
35
+ ENV.fetch(
36
+ Contrib::Propagation::SqlComment::Ext::ENV_DBM_PROPAGATION_MODE,
37
+ Contrib::Propagation::SqlComment::Ext::DISABLED
38
+ )
39
+ end
40
+ o.lazy
41
+ end
30
42
  end
31
43
  end
32
44
  end
@@ -11,7 +11,6 @@ module Datadog
11
11
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_PG_ANALYTICS_ENABLED'.freeze
12
12
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_PG_ANALYTICS_SAMPLE_RATE'.freeze
13
13
  DEFAULT_PEER_SERVICE_NAME = 'pg'.freeze
14
- SPAN_SYSTEM = 'postgresql'.freeze
15
14
  SPAN_EXEC = 'pg.exec'.freeze
16
15
  SPAN_EXEC_PARAMS = 'pg.exec.params'.freeze
17
16
  SPAN_EXEC_PREPARED = 'pg.exec.prepared'.freeze
@@ -24,6 +23,8 @@ module Datadog
24
23
  TAG_DB_NAME = 'pg.db.name'.freeze
25
24
  TAG_COMPONENT = 'pg'.freeze
26
25
  TAG_OPERATION_QUERY = 'query'.freeze
26
+
27
+ TAG_SYSTEM = 'postgresql'.freeze
27
28
  end
28
29
  end
29
30
  end
@@ -5,6 +5,9 @@ require_relative '../analytics'
5
5
  require_relative '../ext'
6
6
  require_relative 'ext'
7
7
 
8
+ require_relative '../propagation/sql_comment'
9
+ require_relative '../propagation/sql_comment/mode'
10
+
8
11
  module Datadog
9
12
  module Tracing
10
13
  module Contrib
@@ -18,68 +21,77 @@ module Datadog
18
21
  # PG::Connection patch methods
19
22
  module InstanceMethods
20
23
  def exec(sql, *args)
21
- trace(Ext::SPAN_EXEC, resource: sql) do
22
- super(sql, *args)
24
+ trace(Ext::SPAN_EXEC, sql: sql) do |sql_statement|
25
+ super(sql_statement, *args)
23
26
  end
24
27
  end
25
28
 
26
29
  def exec_params(sql, params, *args)
27
- trace(Ext::SPAN_EXEC_PARAMS, resource: sql) do
28
- super(sql, params, *args)
30
+ trace(Ext::SPAN_EXEC_PARAMS, sql: sql) do |sql_statement|
31
+ super(sql_statement, params, *args)
29
32
  end
30
33
  end
31
34
 
32
35
  def exec_prepared(statement_name, params, *args)
33
- trace(Ext::SPAN_EXEC_PREPARED, resource: statement_name) do
36
+ trace(Ext::SPAN_EXEC_PREPARED, statement_name: statement_name) do
34
37
  super(statement_name, params, *args)
35
38
  end
36
39
  end
37
40
 
38
41
  def async_exec(sql, *args)
39
- trace(Ext::SPAN_ASYNC_EXEC, resource: sql) do
40
- super(sql, *args)
42
+ trace(Ext::SPAN_ASYNC_EXEC, sql: sql) do |sql_statement|
43
+ super(sql_statement, *args)
41
44
  end
42
45
  end
43
46
 
44
47
  def async_exec_params(sql, params, *args)
45
- trace(Ext::SPAN_ASYNC_EXEC_PARAMS, resource: sql) do
46
- super(sql, params, *args)
48
+ trace(Ext::SPAN_ASYNC_EXEC_PARAMS, sql: sql) do |sql_statement|
49
+ super(sql_statement, params, *args)
47
50
  end
48
51
  end
49
52
 
50
53
  def async_exec_prepared(statement_name, params, *args)
51
- trace(Ext::SPAN_ASYNC_EXEC_PREPARED, resource: statement_name) do
54
+ trace(Ext::SPAN_ASYNC_EXEC_PREPARED, statement_name: statement_name) do
52
55
  super(statement_name, params, *args)
53
56
  end
54
57
  end
55
58
 
56
59
  def sync_exec(sql, *args)
57
- trace(Ext::SPAN_SYNC_EXEC, resource: sql) do
58
- super(sql, *args)
60
+ trace(Ext::SPAN_SYNC_EXEC, sql: sql) do |sql_statement|
61
+ super(sql_statement, *args)
59
62
  end
60
63
  end
61
64
 
62
65
  def sync_exec_params(sql, params, *args)
63
- trace(Ext::SPAN_SYNC_EXEC_PARAMS, resource: sql) do
64
- super(sql, params, *args)
66
+ trace(Ext::SPAN_SYNC_EXEC_PARAMS, sql: sql) do |sql_statement|
67
+ super(sql_statement, params, *args)
65
68
  end
66
69
  end
67
70
 
68
71
  def sync_exec_prepared(statement_name, params, *args)
69
- trace(Ext::SPAN_SYNC_EXEC_PREPARED, resource: statement_name) do
72
+ trace(Ext::SPAN_SYNC_EXEC_PREPARED, statement_name: statement_name) do
70
73
  super(statement_name, params, *args)
71
74
  end
72
75
  end
73
76
 
74
77
  private
75
78
 
76
- def trace(name, resource:)
79
+ def trace(name, sql: nil, statement_name: nil)
77
80
  service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
81
+ resource = statement_name || sql
82
+
78
83
  Tracing.trace(name, service: service, resource: resource, type: Tracing::Metadata::Ext::SQL::TYPE) do |span|
79
84
  annotate_span_with_query!(span, service)
80
85
  # Set analytics sample rate
81
86
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
82
- result = yield
87
+
88
+ if sql
89
+ propagation_mode = Contrib::Propagation::SqlComment::Mode.new(comment_propagation)
90
+ Contrib::Propagation::SqlComment.annotate!(span, propagation_mode)
91
+ propagated_sql_statement = Contrib::Propagation::SqlComment.prepend_comment(sql, span, propagation_mode)
92
+ end
93
+
94
+ result = yield(propagated_sql_statement)
83
95
  annotate_span_with_result!(span, result)
84
96
  result
85
97
  end
@@ -98,7 +110,7 @@ module Datadog
98
110
 
99
111
  span.set_tag(Contrib::Ext::DB::TAG_INSTANCE, db)
100
112
  span.set_tag(Contrib::Ext::DB::TAG_USER, user)
101
- span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::SPAN_SYSTEM)
113
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
102
114
 
103
115
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, host)
104
116
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, port)
@@ -121,6 +133,10 @@ module Datadog
121
133
  def analytics_sample_rate
122
134
  datadog_configuration[:analytics_sample_rate]
123
135
  end
136
+
137
+ def comment_propagation
138
+ datadog_configuration[:comment_propagation]
139
+ end
124
140
  end
125
141
  end
126
142
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: false
4
+
5
+ require 'erb'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ module Propagation
11
+ module SqlComment
12
+ # To be prepended to a sql statement.
13
+ class Comment
14
+ def initialize(hash)
15
+ @hash = hash
16
+ end
17
+
18
+ def to_s
19
+ @string ||= begin
20
+ ret = String.new
21
+
22
+ @hash.each do |key, value|
23
+ next if value.nil?
24
+
25
+ # Url encode
26
+ value = ERB::Util.url_encode(value)
27
+
28
+ # Escape SQL
29
+ ret << "#{key}='#{value}',"
30
+ end
31
+
32
+ # Remove the last `,`
33
+ ret.chop!
34
+
35
+ "/*#{ret}*/"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ # typed: false
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Propagation
7
+ module SqlComment
8
+ module Ext
9
+ ENV_DBM_PROPAGATION_MODE = 'DD_DBM_PROPAGATION_MODE'.freeze
10
+
11
+ # The default mode for sql comment propagation
12
+ DISABLED = 'disabled'.freeze
13
+
14
+ # The `service` mode propagates service configuration
15
+ SERVICE = 'service'.freeze
16
+
17
+ # The `full` mode propagates service configuration + trace context
18
+ FULL = 'full'.freeze
19
+
20
+ # The value should be `true` when `full` mode
21
+ TAG_DBM_TRACE_INJECTED = '_dd.dbm_trace_injected'.freeze
22
+
23
+ KEY_DATABASE_SERVICE = 'dddbs'.freeze
24
+ KEY_ENVIRONMENT = 'dde'.freeze
25
+ KEY_PARENT_SERVICE = 'ddps'.freeze
26
+ KEY_VERSION = 'ddpv'.freeze
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ # typed: false
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Contrib
8
+ module Propagation
9
+ # Implements sql comment propagation related contracts.
10
+ module SqlComment
11
+ Mode = Struct.new(:mode) do
12
+ def enabled?
13
+ service? || full?
14
+ end
15
+
16
+ def service?
17
+ mode == Ext::SERVICE
18
+ end
19
+
20
+ def full?
21
+ mode == Ext::FULL
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ # typed: false
2
+
3
+ require_relative 'sql_comment/comment'
4
+ require_relative 'sql_comment/ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Propagation
10
+ # Implements sql comment propagation related contracts.
11
+ module SqlComment
12
+ def self.annotate!(span_op, mode)
13
+ return unless mode.enabled?
14
+
15
+ # PENDING: Until `traceparent`` implementation in `full` mode
16
+ # span_op.set_tag(Ext::TAG_DBM_TRACE_INJECTED, true) if mode.full?
17
+ end
18
+
19
+ def self.prepend_comment(sql, span_op, mode)
20
+ return sql unless mode.enabled?
21
+
22
+ tags = {
23
+ Ext::KEY_DATABASE_SERVICE => span_op.service,
24
+ Ext::KEY_ENVIRONMENT => datadog_configuration.env,
25
+ Ext::KEY_PARENT_SERVICE => datadog_configuration.service,
26
+ Ext::KEY_VERSION => datadog_configuration.version
27
+ }
28
+
29
+ # PENDING: Until `traceparent`` implementation in `full` mode
30
+ # tags.merge!(trace_context(span_op)) if mode.full?
31
+
32
+ "#{Comment.new(tags)} #{sql}"
33
+ end
34
+
35
+ def self.datadog_configuration
36
+ Datadog.configuration
37
+ end
38
+
39
+ # TODO: Derive from trace
40
+ def self.trace_context(_)
41
+ {
42
+ # traceparent: '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
43
+ }.freeze
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -56,16 +56,18 @@ module Datadog
56
56
  # Find out if this is rack within rack
57
57
  previous_request_span = env[Ext::RACK_ENV_REQUEST_SPAN]
58
58
 
59
+ return @app.call(env) if previous_request_span
60
+
59
61
  # Extract distributed tracing context before creating any spans,
60
62
  # so that all spans will be added to the distributed trace.
61
- if configuration[:distributed_tracing] && previous_request_span.nil?
63
+ if configuration[:distributed_tracing]
62
64
  trace_digest = Tracing::Propagation::HTTP.extract(env)
63
65
  Tracing.continue_trace!(trace_digest)
64
66
  end
65
67
 
66
68
  # Create a root Span to keep track of frontend web servers
67
69
  # (i.e. Apache, nginx) if the header is properly set
68
- frontend_span = compute_queue_time(env) if previous_request_span.nil?
70
+ frontend_span = compute_queue_time(env)
69
71
 
70
72
  trace_options = { span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND }
71
73
  trace_options[:service] = configuration[:service_name] if configuration[:service_name]
@@ -127,6 +129,10 @@ module Datadog
127
129
  request_headers_tags = parse_request_headers(request_header_collection)
128
130
  response_headers_tags = parse_response_headers(headers || {})
129
131
 
132
+ # Since it could be mutated, it would be more accurate to fetch from the original env,
133
+ # e.g. ActionDispatch::ShowExceptions middleware with Rails exceptions_app configuration
134
+ original_request_method = original_env['REQUEST_METHOD']
135
+
130
136
  # request_headers is subject to filtering and configuration so we
131
137
  # get the user agent separately
132
138
  user_agent = parse_user_agent_header(request_header_collection)
@@ -138,11 +144,11 @@ module Datadog
138
144
  # 4. Fallback with verb + status, eq `GET 200`
139
145
  request_span.resource ||=
140
146
  if configuration[:middleware_names] && env['RESPONSE_MIDDLEWARE']
141
- "#{env['RESPONSE_MIDDLEWARE']}##{env['REQUEST_METHOD']}"
147
+ "#{env['RESPONSE_MIDDLEWARE']}##{original_request_method}"
142
148
  elsif trace.resource_override?
143
149
  trace.resource
144
150
  else
145
- "#{env['REQUEST_METHOD']} #{status}".strip
151
+ "#{original_request_method} #{status}".strip
146
152
  end
147
153
 
148
154
  # Overrides the trace resource if it never been set
@@ -161,7 +167,7 @@ module Datadog
161
167
  Contrib::Analytics.set_measured(request_span)
162
168
 
163
169
  if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD).nil?
164
- request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, env['REQUEST_METHOD'])
170
+ request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, original_request_method)
165
171
  end
166
172
 
167
173
  url = parse_url(env, original_env)
@@ -268,10 +274,12 @@ module Datadog
268
274
 
269
275
  query_string.empty? ? path : "#{path}?#{query_string}"
270
276
  else
271
- request_uri
277
+ # normally REQUEST_URI starts at the path, but it
278
+ # might contain the full URL in some cases (e.g WEBrick)
279
+ request_uri.sub(/^#{base_url}/, '')
272
280
  end
273
281
 
274
- ::URI.join(base_url, fullpath).to_s
282
+ base_url + fullpath
275
283
  end
276
284
 
277
285
  def parse_user_agent_header(headers)
@@ -19,6 +19,8 @@ module Datadog
19
19
  TYPE = 'redis'.freeze
20
20
  TAG_COMPONENT = 'redis'.freeze
21
21
  TAG_OPERATION_COMMAND = 'command'.freeze
22
+ TAG_SYSTEM = 'redis'.freeze
23
+ TAG_DATABASE_INDEX = 'db.redis.database_index'.freeze
22
24
  end
23
25
  end
24
26
  end
@@ -21,7 +21,8 @@ module Datadog
21
21
  def call(*args, &block)
22
22
  response = nil
23
23
  Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
24
- span.service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
24
+ span.service = Datadog.configuration_for(redis_instance, :service_name) ||
25
+ datadog_configuration[:service_name]
25
26
  span.span_type = Contrib::Redis::Ext::TYPE
26
27
  span.resource = get_command(args)
27
28
  Contrib::Redis::Tags.set_common_tags(self, span)
@@ -35,7 +36,8 @@ module Datadog
35
36
  def call_pipeline(*args, &block)
36
37
  response = nil
37
38
  Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
38
- span.service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
39
+ span.service = Datadog.configuration_for(redis_instance, :service_name) ||
40
+ datadog_configuration[:service_name]
39
41
  span.span_type = Contrib::Redis::Ext::TYPE
40
42
  commands = get_pipeline_commands(args)
41
43
  span.resource = commands.any? ? commands.join("\n") : '(none)'
@@ -12,6 +12,42 @@ module Datadog
12
12
  module Patcher
13
13
  include Contrib::Patcher
14
14
 
15
+ # Patch for redis instance
16
+ module InstancePatch
17
+ def self.included(base)
18
+ base.prepend(InstanceMethods)
19
+ end
20
+
21
+ # Instance method patch for redis instance
22
+ module InstanceMethods
23
+ def initialize(options = {})
24
+ options[:redis_instance] = self
25
+
26
+ super(options)
27
+ end
28
+ end
29
+ end
30
+
31
+ # Patch for redis client
32
+ module ClientPatch
33
+ def self.included(base)
34
+ base.prepend(InstanceMethods)
35
+ end
36
+
37
+ # Instance method patch for redis client
38
+ module InstanceMethods
39
+ def initialize(options = {})
40
+ @redis_instance = options.delete(:redis_instance)
41
+
42
+ super(options)
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :redis_instance
48
+ end
49
+ end
50
+
15
51
  module_function
16
52
 
17
53
  def target_version
@@ -26,6 +62,11 @@ module Datadog
26
62
  require_relative 'quantize'
27
63
  require_relative 'instrumentation'
28
64
 
65
+ # InstancePatch and ClientPatch allows the client object to access pin on redis instance
66
+ ::Redis.include(InstancePatch)
67
+ ::Redis::Client.include(ClientPatch)
68
+
69
+ # TODO: To support redis-rb 5.x, Redis::Client -> RedisClient
29
70
  ::Redis::Client.include(Instrumentation)
30
71
  end
31
72
  end
@@ -3,6 +3,7 @@
3
3
  require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative 'ext'
6
+ require_relative '../ext'
6
7
 
7
8
  module Datadog
8
9
  module Tracing
@@ -22,8 +23,12 @@ module Datadog
22
23
  # Set analytics sample rate
23
24
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
24
25
 
26
+ span.set_tag Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM
27
+
25
28
  span.set_tag Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, client.host
26
29
  span.set_tag Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, client.port
30
+
31
+ span.set_tag Ext::TAG_DATABASE_INDEX, client.db.to_s
27
32
  span.set_tag Ext::TAG_DB, client.db
28
33
  span.set_tag Ext::TAG_RAW_COMMAND, span.resource if show_command_args?
29
34
  end
@@ -34,6 +34,8 @@ module Datadog
34
34
  def datadog_tag_request(uri, span)
35
35
  span.resource = method.to_s.upcase
36
36
 
37
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
38
+
37
39
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
38
40
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
39
41