datadog-statsd-schema 0.1.1 → 0.1.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.
@@ -5,22 +5,58 @@ require "dry-types"
5
5
  require_relative "tag_definition"
6
6
  require_relative "metric_definition"
7
7
 
8
+ # @author Datadog Team
9
+ # @since 0.1.0
8
10
  module Datadog
9
11
  class Statsd
12
+ # Schema definition and validation module for StatsD metrics
10
13
  module Schema
14
+ # Represents a namespace in the metric schema hierarchy
15
+ # Namespaces contain tags, metrics, and nested namespaces, providing organization and scoping
16
+ # @example Basic namespace
17
+ # namespace = Namespace.new(
18
+ # name: :web,
19
+ # description: "Web application metrics"
20
+ # )
21
+ # @example Namespace with tags and metrics
22
+ # namespace = Namespace.new(
23
+ # name: :api,
24
+ # tags: { controller: tag_def, action: tag_def2 },
25
+ # metrics: { requests: metric_def }
26
+ # )
27
+ # @author Datadog Team
28
+ # @since 0.1.0
11
29
  class Namespace < Dry::Struct
12
- # Include the types module for easier access
30
+ # Include the types module for easier access to Dry::Types
13
31
  module Types
14
32
  include Dry.Types()
15
33
  end
16
34
 
35
+ # The namespace name as a symbol
36
+ # @return [Symbol] Namespace name
17
37
  attribute :name, Types::Strict::Symbol
38
+
39
+ # Hash of tag definitions within this namespace
40
+ # @return [Hash<Symbol, TagDefinition>] Tag name to TagDefinition mapping
18
41
  attribute :tags, Types::Hash.map(Types::Symbol, TagDefinition).default({}.freeze)
42
+
43
+ # Hash of metric definitions within this namespace
44
+ # @return [Hash<Symbol, MetricDefinition>] Metric name to MetricDefinition mapping
19
45
  attribute :metrics, Types::Hash.map(Types::Symbol, MetricDefinition).default({}.freeze)
46
+
47
+ # Hash of nested namespaces within this namespace
48
+ # @return [Hash<Symbol, Namespace>] Namespace name to Namespace mapping
20
49
  attribute :namespaces, Types::Hash.map(Types::Symbol, Namespace).default({}.freeze)
50
+
51
+ # Human-readable description of this namespace
52
+ # @return [String, nil] Description text
21
53
  attribute :description, Types::String.optional.default(nil)
22
54
 
23
- # Get the full path of this namespace
55
+ # Get the full path of this namespace including parent namespaces
56
+ # @param parent_path [Array<Symbol>] Array of parent namespace names
57
+ # @return [Array<Symbol>] Full namespace path
58
+ # @example
59
+ # namespace.full_path([:web, :api]) # => [:web, :api, :request]
24
60
  def full_path(parent_path = [])
25
61
  return [name] if parent_path.empty?
26
62
 
@@ -28,72 +64,109 @@ module Datadog
28
64
  end
29
65
 
30
66
  # Find a metric by name within this namespace
67
+ # @param metric_name [String, Symbol] Name of the metric to find
68
+ # @return [MetricDefinition, nil] The metric definition or nil if not found
69
+ # @example
70
+ # namespace.find_metric(:page_views) # => MetricDefinition instance
31
71
  def find_metric(metric_name)
32
72
  metric_symbol = metric_name.to_sym
33
73
  metrics[metric_symbol]
34
74
  end
35
75
 
36
76
  # Find a tag definition by name within this namespace
77
+ # @param tag_name [String, Symbol] Name of the tag to find
78
+ # @return [TagDefinition, nil] The tag definition or nil if not found
79
+ # @example
80
+ # namespace.find_tag(:controller) # => TagDefinition instance
37
81
  def find_tag(tag_name)
38
82
  tag_symbol = tag_name.to_sym
39
83
  tags[tag_symbol]
40
84
  end
41
85
 
42
86
  # Find a nested namespace by name
87
+ # @param namespace_name [String, Symbol] Name of the namespace to find
88
+ # @return [Namespace, nil] The nested namespace or nil if not found
89
+ # @example
90
+ # namespace.find_namespace(:api) # => Namespace instance
43
91
  def find_namespace(namespace_name)
44
92
  namespace_symbol = namespace_name.to_sym
45
93
  namespaces[namespace_symbol]
46
94
  end
47
95
 
48
- # Add a new metric to this namespace
96
+ # Add a new metric to this namespace (returns new namespace instance)
97
+ # @param metric_definition [MetricDefinition] The metric definition to add
98
+ # @return [Namespace] New namespace instance with the added metric
49
99
  def add_metric(metric_definition)
50
100
  new(metrics: metrics.merge(metric_definition.name => metric_definition))
51
101
  end
52
102
 
53
- # Add a new tag definition to this namespace
103
+ # Add a new tag definition to this namespace (returns new namespace instance)
104
+ # @param tag_definition [TagDefinition] The tag definition to add
105
+ # @return [Namespace] New namespace instance with the added tag
54
106
  def add_tag(tag_definition)
55
107
  new(tags: tags.merge(tag_definition.name => tag_definition))
56
108
  end
57
109
 
58
- # Add a nested namespace
110
+ # Add a nested namespace (returns new namespace instance)
111
+ # @param namespace [Namespace] The namespace to add
112
+ # @return [Namespace] New namespace instance with the added namespace
59
113
  def add_namespace(namespace)
60
114
  new(namespaces: namespaces.merge(namespace.name => namespace))
61
115
  end
62
116
 
63
117
  # Get all metric names in this namespace (not including nested)
118
+ # @return [Array<Symbol>] Array of metric names
64
119
  def metric_names
65
120
  metrics.keys
66
121
  end
67
122
 
68
123
  # Get all tag names in this namespace
124
+ # @return [Array<Symbol>] Array of tag names
69
125
  def tag_names
70
126
  tags.keys
71
127
  end
72
128
 
73
129
  # Get all nested namespace names
130
+ # @return [Array<Symbol>] Array of namespace names
74
131
  def namespace_names
75
132
  namespaces.keys
76
133
  end
77
134
 
78
135
  # Check if this namespace contains a metric
136
+ # @param metric_name [String, Symbol] Name of the metric to check
137
+ # @return [Boolean] true if metric exists
79
138
  def has_metric?(metric_name)
80
139
  metric_symbol = metric_name.to_sym
81
140
  metrics.key?(metric_symbol)
82
141
  end
83
142
 
84
143
  # Check if this namespace contains a tag definition
144
+ # @param tag_name [String, Symbol] Name of the tag to check
145
+ # @return [Boolean] true if tag exists
85
146
  def has_tag?(tag_name)
86
147
  tag_symbol = tag_name.to_sym
87
148
  tags.key?(tag_symbol)
88
149
  end
89
150
 
90
151
  # Check if this namespace contains a nested namespace
152
+ # @param namespace_name [String, Symbol] Name of the namespace to check
153
+ # @return [Boolean] true if namespace exists
91
154
  def has_namespace?(namespace_name)
92
155
  namespace_symbol = namespace_name.to_sym
93
156
  namespaces.key?(namespace_symbol)
94
157
  end
95
158
 
96
159
  # Get all metrics recursively including from nested namespaces
160
+ # @param path [Array<Symbol>] Current namespace path (used for recursion)
161
+ # @return [Hash] Hash mapping full metric names to metric info
162
+ # @example
163
+ # {
164
+ # "web.page_views" => {
165
+ # definition: MetricDefinition,
166
+ # namespace_path: [:web],
167
+ # namespace: Namespace
168
+ # }
169
+ # }
97
170
  def all_metrics(path = [])
98
171
  # Filter out :root from the path to avoid it appearing in metric names
99
172
  current_path = path + [name]
@@ -119,11 +192,14 @@ module Datadog
119
192
  end
120
193
 
121
194
  # Get all tag definitions including inherited from parent namespaces
195
+ # @param parent_tags [Hash] Tag definitions from parent namespaces
196
+ # @return [Hash<Symbol, TagDefinition>] Combined tag definitions
122
197
  def effective_tags(parent_tags = {})
123
198
  parent_tags.merge(tags)
124
199
  end
125
200
 
126
201
  # Validate that all tag references in metrics exist
202
+ # @return [Array<String>] Array of validation error messages
127
203
  def validate_tag_references
128
204
  errors = []
129
205
 
@@ -148,6 +224,10 @@ module Datadog
148
224
  end
149
225
 
150
226
  # Find metric by path (e.g., "request.duration" within web namespace)
227
+ # @param path [String] Dot-separated path to the metric
228
+ # @return [MetricDefinition, nil] The metric definition or nil if not found
229
+ # @example
230
+ # namespace.find_metric_by_path("api.requests") # => MetricDefinition
151
231
  def find_metric_by_path(path)
152
232
  parts = path.split(".")
153
233
 
@@ -167,6 +247,10 @@ module Datadog
167
247
  end
168
248
 
169
249
  # Get namespace by path (e.g., "web.request")
250
+ # @param path [String] Dot-separated path to the namespace
251
+ # @return [Namespace, nil] The namespace or nil if not found
252
+ # @example
253
+ # root_namespace.find_namespace_by_path("web.api") # => Namespace
170
254
  def find_namespace_by_path(path)
171
255
  return self if path.empty?
172
256
 
@@ -186,11 +270,13 @@ module Datadog
186
270
  end
187
271
 
188
272
  # Count total metrics including nested namespaces
273
+ # @return [Integer] Total number of metrics in this namespace tree
189
274
  def total_metrics_count
190
275
  metrics.count + namespaces.values.sum(&:total_metrics_count)
191
276
  end
192
277
 
193
278
  # Count total namespaces including nested
279
+ # @return [Integer] Total number of namespaces in this namespace tree
194
280
  def total_namespaces_count
195
281
  namespaces.count + namespaces.values.sum(&:total_namespaces_count)
196
282
  end
@@ -4,18 +4,50 @@ require_relative "namespace"
4
4
  require_relative "tag_definition"
5
5
  require_relative "metric_definition"
6
6
 
7
+ # @author Datadog Team
8
+ # @since 0.1.0
7
9
  module Datadog
8
10
  class Statsd
11
+ # Schema definition and validation module for StatsD metrics
9
12
  module Schema
13
+ # Builder class for constructing metric schemas using a DSL
14
+ # Provides a fluent interface for defining namespaces, tags, and metrics
15
+ # @example Basic schema building
16
+ # builder = SchemaBuilder.new
17
+ # builder.namespace :web do
18
+ # tags do
19
+ # tag :controller, values: %w[users posts]
20
+ # end
21
+ # metrics do
22
+ # counter :page_views, tags: { required: [:controller] }
23
+ # end
24
+ # end
25
+ # schema = builder.build
26
+ # @author Datadog Team
27
+ # @since 0.1.0
10
28
  class SchemaBuilder
11
- attr_reader :transformers, :root_namespace
29
+ # Hash of transformer functions available for tag transformations
30
+ # @return [Hash<Symbol, Proc>] Transformer name to proc mapping
31
+ attr_reader :transformers
12
32
 
33
+ # The root namespace of the schema being built
34
+ # @return [Namespace] Root namespace instance
35
+ attr_reader :root_namespace
36
+
37
+ # Initialize a new schema builder
13
38
  def initialize
14
39
  @transformers = {}
15
40
  @root_namespace = Namespace.new(name: :root)
16
41
  end
17
42
 
18
43
  # Define transformers that can be used by tag definitions
44
+ # @yield [TransformerBuilder] Block for defining transformers
45
+ # @return [Hash<Symbol, Proc>] Hash of defined transformers
46
+ # @example
47
+ # builder.transformers do
48
+ # underscore { |value| value.to_s.underscore }
49
+ # downcase { |value| value.to_s.downcase }
50
+ # end
19
51
  def transformers(&)
20
52
  return @transformers unless block_given?
21
53
 
@@ -23,6 +55,14 @@ module Datadog
23
55
  end
24
56
 
25
57
  # Define a namespace
58
+ # @param name [Symbol] Name of the namespace
59
+ # @yield [NamespaceBuilder] Block for defining namespace contents
60
+ # @return [void]
61
+ # @example
62
+ # builder.namespace :web do
63
+ # description "Web application metrics"
64
+ # # ... tags and metrics definitions
65
+ # end
26
66
  def namespace(name, &)
27
67
  builder = NamespaceBuilder.new(name, @transformers)
28
68
  builder.instance_eval(&) if block_given?
@@ -32,35 +72,76 @@ module Datadog
32
72
  end
33
73
 
34
74
  # Build the final schema (returns the root namespace)
75
+ # @return [Namespace] The root namespace containing the entire schema
35
76
  def build
36
77
  @root_namespace
37
78
  end
38
79
 
39
80
  # Validate the schema for consistency
81
+ # @raise [SchemaError] If schema validation fails
82
+ # @return [void]
40
83
  def validate!
41
84
  errors = @root_namespace.validate_tag_references
42
85
  raise SchemaError, "Schema validation failed: #{errors.join(", ")}" unless errors.empty?
43
86
  end
44
87
 
45
- # Helper class for building transformers
88
+ # Helper class for building transformers within the DSL
89
+ # @api private
46
90
  class TransformerBuilder
91
+ # Initialize with the transformers hash
92
+ # @param transformers [Hash] Hash to store transformer definitions
47
93
  def initialize(transformers)
48
94
  @transformers = transformers
49
95
  end
50
96
 
97
+ # Dynamic method to define transformers
98
+ # @param name [Symbol] Name of the transformer
99
+ # @param proc [Proc] Transformer procedure (alternative to block)
100
+ # @yield [Object] Value to transform
101
+ # @return [void]
51
102
  def method_missing(name, proc = nil, &block)
52
103
  @transformers[name.to_sym] = proc || block
53
104
  end
54
105
 
106
+ # Always respond to any method for transformer definition
107
+ # @param _name [Symbol] Method name
108
+ # @param _include_private [Boolean] Whether to include private methods
109
+ # @return [Boolean] Always true
55
110
  def respond_to_missing?(_name, _include_private = false)
56
111
  true
57
112
  end
58
113
  end
59
114
 
60
- # Helper class for building namespaces
115
+ # Helper class for building namespaces within the DSL
116
+ # @api private
61
117
  class NamespaceBuilder
62
- attr_reader :name, :transformers, :tags, :metrics, :namespaces, :description
118
+ # Name of the namespace being built
119
+ # @return [Symbol] Namespace name
120
+ attr_reader :name
121
+
122
+ # Available transformers for tags
123
+ # @return [Hash<Symbol, Proc>] Transformer definitions
124
+ attr_reader :transformers
125
+
126
+ # Tag definitions for this namespace
127
+ # @return [Hash<Symbol, TagDefinition>] Tag definitions
128
+ attr_reader :tags
129
+
130
+ # Metric definitions for this namespace
131
+ # @return [Hash<Symbol, MetricDefinition>] Metric definitions
132
+ attr_reader :metrics
133
+
134
+ # Nested namespaces
135
+ # @return [Hash<Symbol, Namespace>] Nested namespace definitions
136
+ attr_reader :namespaces
137
+
138
+ # Description of this namespace
139
+ # @return [String, nil] Description text
140
+ attr_reader :description
63
141
 
142
+ # Initialize a new namespace builder
143
+ # @param name [Symbol] Name of the namespace
144
+ # @param transformers [Hash] Available transformer functions
64
145
  def initialize(name, transformers = {})
65
146
  @name = name.to_sym
66
147
  @transformers = transformers
@@ -71,27 +152,48 @@ module Datadog
71
152
  end
72
153
 
73
154
  # Set description for this namespace
155
+ # @param desc [String] Description text
156
+ # @return [void]
74
157
  def description(desc)
75
158
  @description = desc
76
159
  end
77
160
 
78
161
  # Define tags for this namespace
162
+ # @yield [TagsBuilder] Block for defining tags
163
+ # @return [void]
164
+ # @example
165
+ # tags do
166
+ # tag :controller, values: %w[users posts]
167
+ # tag :action, values: %w[index show create]
168
+ # end
79
169
  def tags(&)
80
170
  TagsBuilder.new(@tags, @transformers).instance_eval(&)
81
171
  end
82
172
 
83
173
  # Define metrics for this namespace
174
+ # @yield [MetricsBuilder] Block for defining metrics
175
+ # @return [void]
176
+ # @example
177
+ # metrics do
178
+ # counter :page_views, tags: { required: [:controller] }
179
+ # gauge :memory_usage
180
+ # end
84
181
  def metrics(&)
85
182
  MetricsBuilder.new(@metrics, @transformers).instance_eval(&)
86
183
  end
87
184
 
88
185
  # Define nested namespace
186
+ # @param name [Symbol] Name of the nested namespace
187
+ # @yield [NamespaceBuilder] Block for defining nested namespace
188
+ # @return [void]
89
189
  def namespace(name, &)
90
190
  builder = NamespaceBuilder.new(name, @transformers)
91
191
  builder.instance_eval(&) if block_given?
92
192
  @namespaces[name.to_sym] = builder.build
93
193
  end
94
194
 
195
+ # Build the namespace instance
196
+ # @return [Namespace] The constructed namespace
95
197
  def build
96
198
  Namespace.new(
97
199
  name: @name,
@@ -104,12 +206,27 @@ module Datadog
104
206
  end
105
207
 
106
208
  # Helper class for building tags within a namespace
209
+ # @api private
107
210
  class TagsBuilder
211
+ # Initialize with tags hash and transformers
212
+ # @param tags [Hash] Hash to store tag definitions
213
+ # @param transformers [Hash] Available transformer functions
108
214
  def initialize(tags, transformers)
109
215
  @tags = tags
110
216
  @transformers = transformers
111
217
  end
112
218
 
219
+ # Define a tag
220
+ # @param name [Symbol] Name of the tag
221
+ # @param options [Hash] Tag options
222
+ # @option options [Array, Regexp, Proc] :values Allowed values
223
+ # @option options [Symbol] :type Data type (:string, :integer, :symbol)
224
+ # @option options [Array<Symbol>] :transform Transformation functions to apply
225
+ # @option options [Proc] :validate Custom validation function
226
+ # @return [void]
227
+ # @example
228
+ # tag :controller, values: %w[users posts], type: :string
229
+ # tag :status_code, type: :integer, validate: ->(code) { (100..599).include?(code) }
113
230
  def tag(name, **options)
114
231
  tag_def = TagDefinition.new(
115
232
  name: name.to_sym,
@@ -124,7 +241,11 @@ module Datadog
124
241
  end
125
242
 
126
243
  # Helper class for building metrics within a namespace
244
+ # @api private
127
245
  class MetricsBuilder
246
+ # Initialize with metrics hash and transformers
247
+ # @param metrics [Hash] Hash to store metric definitions
248
+ # @param transformers [Hash] Available transformer functions
128
249
  def initialize(metrics, transformers)
129
250
  @metrics = metrics
130
251
  @transformers = transformers
@@ -132,6 +253,9 @@ module Datadog
132
253
  end
133
254
 
134
255
  # Define a nested namespace for metrics
256
+ # @param name [Symbol] Namespace name
257
+ # @yield Block for defining metrics within the namespace
258
+ # @return [void]
135
259
  def namespace(name, &)
136
260
  @current_namespace = name.to_sym
137
261
  instance_eval(&)
@@ -140,6 +264,15 @@ module Datadog
140
264
 
141
265
  # Define individual metric types
142
266
  %i[counter gauge histogram distribution timing set].each do |metric_type|
267
+ # Define a metric of the specified type
268
+ # @param name [Symbol] Metric name
269
+ # @param options [Hash] Metric options
270
+ # @option options [String] :description Human-readable description
271
+ # @option options [Hash, Array] :tags Tag configuration
272
+ # @option options [String] :inherit_tags Path to metric to inherit from
273
+ # @option options [String] :units Unit of measurement
274
+ # @yield [MetricBuilder] Block for additional metric configuration
275
+ # @return [void]
143
276
  define_method(metric_type) do |name, **options, &block|
144
277
  metric_name = @current_namespace ? :"#{@current_namespace}_#{name}" : name.to_sym
145
278
 
@@ -166,6 +299,9 @@ module Datadog
166
299
 
167
300
  private
168
301
 
302
+ # Extract allowed tags from options
303
+ # @param options [Hash] Metric options
304
+ # @return [Array<Symbol>] Allowed tag names
169
305
  def extract_allowed_tags(options)
170
306
  tags_option = options[:tags]
171
307
  return [] unless tags_option
@@ -177,6 +313,9 @@ module Datadog
177
313
  end
178
314
  end
179
315
 
316
+ # Extract required tags from options
317
+ # @param options [Hash] Metric options
318
+ # @return [Array<Symbol>] Required tag names
180
319
  def extract_required_tags(options)
181
320
  tags_option = options[:tags]
182
321
  return [] unless tags_option
@@ -190,15 +329,26 @@ module Datadog
190
329
  end
191
330
 
192
331
  # Helper class for building individual metrics with block syntax
332
+ # @api private
193
333
  class MetricBuilder
334
+ # Initialize with a metric definition
335
+ # @param metric_def [MetricDefinition] Initial metric definition
194
336
  def initialize(metric_def)
195
337
  @metric_def = metric_def
196
338
  end
197
339
 
340
+ # Set metric description
341
+ # @param desc [String] Description text
342
+ # @return [void]
198
343
  def description(desc)
199
344
  @metric_def = @metric_def.new(description: desc)
200
345
  end
201
346
 
347
+ # Configure metric tags
348
+ # @param options [Hash] Tag configuration
349
+ # @option options [Array] :allowed Allowed tag names
350
+ # @option options [Array] :required Required tag names
351
+ # @return [void]
202
352
  def tags(**options)
203
353
  allowed = Array(options[:allowed] || []).map(&:to_sym)
204
354
  required = Array(options[:required] || []).map(&:to_sym)
@@ -209,14 +359,22 @@ module Datadog
209
359
  )
210
360
  end
211
361
 
362
+ # Set metric units
363
+ # @param unit_name [String] Unit description
364
+ # @return [void]
212
365
  def units(unit_name)
213
366
  @metric_def = @metric_def.new(units: unit_name)
214
367
  end
215
368
 
369
+ # Set metric inheritance
370
+ # @param metric_path [String] Path to parent metric
371
+ # @return [void]
216
372
  def inherit_tags(metric_path)
217
373
  @metric_def = @metric_def.new(inherit_tags: metric_path)
218
374
  end
219
375
 
376
+ # Build the final metric definition
377
+ # @return [MetricDefinition] The constructed metric definition
220
378
  def build
221
379
  @metric_def
222
380
  end
@@ -3,23 +3,65 @@
3
3
  require "dry-struct"
4
4
  require "dry-types"
5
5
 
6
+ # @author Datadog Team
7
+ # @since 0.1.0
6
8
  module Datadog
7
9
  class Statsd
10
+ # Schema definition and validation module for StatsD metrics
8
11
  module Schema
12
+ # Represents a tag definition within a schema namespace
13
+ # Defines validation rules, allowed values, transformations, and type constraints for tags
14
+ # @example Basic tag definition
15
+ # tag_def = TagDefinition.new(
16
+ # name: :environment,
17
+ # values: [:production, :staging, :development],
18
+ # type: :symbol
19
+ # )
20
+ # @example Tag with custom validation
21
+ # tag_def = TagDefinition.new(
22
+ # name: :user_id,
23
+ # type: :integer,
24
+ # validate: ->(value) { value > 0 }
25
+ # )
26
+ # @author Datadog Team
27
+ # @since 0.1.0
9
28
  class TagDefinition < Dry::Struct
10
- # Include the types module for easier access
29
+ # Include the types module for easier access to Dry::Types
11
30
  module Types
12
31
  include Dry.Types()
13
32
  end
14
33
 
34
+ # The tag name as a symbol
35
+ # @return [Symbol] Tag name
15
36
  attribute :name, Types::Strict::Symbol
16
- attribute :values, Types::Any.optional.default(nil) # Allow any type: Array, Regexp, Proc, or single value
37
+
38
+ # Allowed values for this tag (can be Array, Regexp, Proc, or single value)
39
+ # @return [Array, Regexp, Proc, Object, nil] Allowed values constraint
40
+ attribute :values, Types::Any.optional.default(nil)
41
+
42
+ # The expected data type for tag values
43
+ # @return [Symbol] Type constraint (:string, :integer, :symbol)
17
44
  attribute :type, Types::Strict::Symbol.default(:string)
45
+
46
+ # Array of transformation functions to apply to values
47
+ # @return [Array<Symbol>] Transformation function names
18
48
  attribute :transform, Types::Array.of(Types::Symbol).default([].freeze)
19
- attribute :validate, Types::Any.optional.default(nil) # Proc for custom validation
49
+
50
+ # Custom validation procedure for tag values
51
+ # @return [Proc, nil] Custom validation function
52
+ attribute :validate, Types::Any.optional.default(nil)
53
+
54
+ # The namespace this tag belongs to
55
+ # @return [Symbol, nil] Namespace name
20
56
  attribute :namespace, Types::Strict::Symbol.optional.default(nil)
21
57
 
22
- # Check if a value is allowed for this tag
58
+ # Check if a value is allowed for this tag according to the values constraint
59
+ # @param value [Object] The value to check
60
+ # @return [Boolean] true if the value is allowed
61
+ # @example
62
+ # tag_def = TagDefinition.new(name: :env, values: [:prod, :dev])
63
+ # tag_def.allows_value?(:prod) # => true
64
+ # tag_def.allows_value?(:test) # => false
23
65
  def allows_value?(value)
24
66
  return true if values.nil? # No restrictions
25
67
 
@@ -35,7 +77,14 @@ module Datadog
35
77
  end
36
78
  end
37
79
 
38
- # Apply transformations to a value
80
+ # Apply transformations to a value using the provided transformer functions
81
+ # @param value [Object] The value to transform
82
+ # @param transformers [Hash<Symbol, Proc>] Hash of transformer name to proc mappings
83
+ # @return [Object] The transformed value
84
+ # @example
85
+ # tag_def = TagDefinition.new(name: :service, transform: [:downcase])
86
+ # transformers = { downcase: ->(val) { val.to_s.downcase } }
87
+ # tag_def.transform_value("WEB-SERVICE", transformers) # => "web-service"
39
88
  def transform_value(value, transformers = {})
40
89
  return value if transform.empty?
41
90
 
@@ -45,7 +94,18 @@ module Datadog
45
94
  end
46
95
  end
47
96
 
48
- # Validate a value using custom validation if present
97
+ # Validate a value using type checking, transformations, and custom validation
98
+ # @param value [Object] The value to validate
99
+ # @param transformers [Hash<Symbol, Proc>] Hash of transformer name to proc mappings
100
+ # @return [Boolean] true if the value is valid
101
+ # @example
102
+ # tag_def = TagDefinition.new(
103
+ # name: :port,
104
+ # type: :integer,
105
+ # validate: ->(val) { val > 0 && val < 65536 }
106
+ # )
107
+ # tag_def.valid_value?(8080) # => true
108
+ # tag_def.valid_value?(-1) # => false
49
109
  def valid_value?(value, transformers = {})
50
110
  transformed_value = transform_value(value, transformers)
51
111
 
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @author Datadog Team
4
+ # @since 0.1.0
3
5
  module Datadog
4
6
  class Statsd
7
+ # Schema definition and validation module for StatsD metrics
5
8
  module Schema
6
- VERSION = "0.1.1"
9
+ # Current version of the datadog-statsd-schema gem
10
+ # @return [String] The semantic version string
11
+ VERSION = "0.1.2"
7
12
  end
8
13
  end
9
14
  end