Class: Datadog::Statsd::Schema::Namespace

Inherits:
Dry::Struct
  • Object
show all
Defined in:
lib/datadog/statsd/schema/namespace.rb

Overview

Represents a namespace in the metric schema hierarchy Namespaces contain tags, metrics, and nested namespaces, providing organization and scoping

Examples:

Basic namespace

namespace = Namespace.new(
  name: :web,
  description: "Web application metrics"
)

Namespace with tags and metrics

namespace = Namespace.new(
  name: :api,
  tags: { controller: tag_def, action: tag_def2 },
  metrics: { requests: metric_def }
)

Author:

  • Datadog Team

Since:

  • 0.1.0

Defined Under Namespace

Modules: Types

Instance Method Summary collapse

Instance Method Details

#add_metric(metric_definition) ⇒ Namespace

Add a new metric to this namespace (returns new namespace instance)

Since:

  • 0.1.0



99
100
101
# File 'lib/datadog/statsd/schema/namespace.rb', line 99

def add_metric(metric_definition)
  new(metrics: metrics.merge(metric_definition.name => metric_definition))
end

#add_namespace(namespace) ⇒ Namespace

Add a nested namespace (returns new namespace instance)

Since:

  • 0.1.0



113
114
115
# File 'lib/datadog/statsd/schema/namespace.rb', line 113

def add_namespace(namespace)
  new(namespaces: namespaces.merge(namespace.name => namespace))
end

#add_tag(tag_definition) ⇒ Namespace

Add a new tag definition to this namespace (returns new namespace instance)

Since:

  • 0.1.0



106
107
108
# File 'lib/datadog/statsd/schema/namespace.rb', line 106

def add_tag(tag_definition)
  new(tags: tags.merge(tag_definition.name => tag_definition))
end

#all_metrics(path = []) ⇒ Hash

Get all metrics recursively including from nested namespaces

Examples:

{
  "web.page_views" => {
    definition: MetricDefinition,
    namespace_path: [:web],
    namespace: Namespace
  }
}

Since:

  • 0.1.0



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/datadog/statsd/schema/namespace.rb', line 170

def all_metrics(path = [])
  # Filter out :root from the path to avoid it appearing in metric names
  current_path = path + [name]
  filtered_path = current_path.reject { |part| part == :root }
  result = {}

  # Add metrics from this namespace
  metrics.each do |_metric_name, metric_def|
    full_metric_name = metric_def.full_name(filtered_path)
    result[full_metric_name] = {
      definition: metric_def,
      namespace_path: filtered_path,
      namespace: self
    }
  end

  # Add metrics from nested namespaces recursively
  namespaces.each do |_, nested_namespace|
    result.merge!(nested_namespace.all_metrics(current_path))
  end

  result
end

#descriptionString?

Human-readable description of this namespace

Since:

  • 0.1.0



53
# File 'lib/datadog/statsd/schema/namespace.rb', line 53

attribute :description, Types::String.optional.default(nil)

#effective_tags(parent_tags = {}) ⇒ Hash<Symbol, TagDefinition>

Get all tag definitions including inherited from parent namespaces

Since:

  • 0.1.0



197
198
199
# File 'lib/datadog/statsd/schema/namespace.rb', line 197

def effective_tags(parent_tags = {})
  parent_tags.merge(tags)
end

#find_metric(metric_name) ⇒ MetricDefinition?

Find a metric by name within this namespace

Examples:

namespace.find_metric(:page_views)  # => MetricDefinition instance

Since:

  • 0.1.0



71
72
73
74
# File 'lib/datadog/statsd/schema/namespace.rb', line 71

def find_metric(metric_name)
  metric_symbol = metric_name.to_sym
  metrics[metric_symbol]
end

#find_metric_by_path(path) ⇒ MetricDefinition?

Find metric by path (e.g., “request.duration” within web namespace)

Examples:

namespace.find_metric_by_path("api.requests")  # => MetricDefinition

Since:

  • 0.1.0



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/datadog/statsd/schema/namespace.rb', line 231

def find_metric_by_path(path)
  parts = path.split(".")

  if parts.length == 1
    # Single part, look for metric in this namespace
    find_metric(parts.first)
  else
    # Multiple parts, navigate to nested namespace
    namespace_name = parts.first
    remaining_path = parts[1..-1].join(".")

    nested_namespace = find_namespace(namespace_name)
    return nil unless nested_namespace

    nested_namespace.find_metric_by_path(remaining_path)
  end
end

#find_namespace(namespace_name) ⇒ Namespace?

Find a nested namespace by name

Examples:

namespace.find_namespace(:api)  # => Namespace instance

Since:

  • 0.1.0



91
92
93
94
# File 'lib/datadog/statsd/schema/namespace.rb', line 91

def find_namespace(namespace_name)
  namespace_symbol = namespace_name.to_sym
  namespaces[namespace_symbol]
end

#find_namespace_by_path(path) ⇒ Namespace?

Get namespace by path (e.g., “web.request”)

Examples:

root_namespace.find_namespace_by_path("web.api")  # => Namespace

Since:

  • 0.1.0



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/datadog/statsd/schema/namespace.rb', line 254

def find_namespace_by_path(path)
  return self if path.empty?

  parts = path.split(".")

  if parts.length == 1
    find_namespace(parts.first)
  else
    namespace_name = parts.first
    remaining_path = parts[1..-1].join(".")

    nested_namespace = find_namespace(namespace_name)
    return nil unless nested_namespace

    nested_namespace.find_namespace_by_path(remaining_path)
  end
end

#find_tag(tag_name) ⇒ TagDefinition?

Find a tag definition by name within this namespace

Examples:

namespace.find_tag(:controller)  # => TagDefinition instance

Since:

  • 0.1.0



81
82
83
84
# File 'lib/datadog/statsd/schema/namespace.rb', line 81

def find_tag(tag_name)
  tag_symbol = tag_name.to_sym
  tags[tag_symbol]
end

#full_path(parent_path = []) ⇒ Array<Symbol>

Get the full path of this namespace including parent namespaces

Examples:

namespace.full_path([:web, :api])  # => [:web, :api, :request]

Since:

  • 0.1.0



60
61
62
63
64
# File 'lib/datadog/statsd/schema/namespace.rb', line 60

def full_path(parent_path = [])
  return [name] if parent_path.empty?

  parent_path + [name]
end

#has_metric?(metric_name) ⇒ Boolean

Check if this namespace contains a metric

Since:

  • 0.1.0



138
139
140
141
# File 'lib/datadog/statsd/schema/namespace.rb', line 138

def has_metric?(metric_name)
  metric_symbol = metric_name.to_sym
  metrics.key?(metric_symbol)
end

#has_namespace?(namespace_name) ⇒ Boolean

Check if this namespace contains a nested namespace

Since:

  • 0.1.0



154
155
156
157
# File 'lib/datadog/statsd/schema/namespace.rb', line 154

def has_namespace?(namespace_name)
  namespace_symbol = namespace_name.to_sym
  namespaces.key?(namespace_symbol)
end

#has_tag?(tag_name) ⇒ Boolean

Check if this namespace contains a tag definition

Since:

  • 0.1.0



146
147
148
149
# File 'lib/datadog/statsd/schema/namespace.rb', line 146

def has_tag?(tag_name)
  tag_symbol = tag_name.to_sym
  tags.key?(tag_symbol)
end

#metric_namesArray<Symbol>

Get all metric names in this namespace (not including nested)

Since:

  • 0.1.0



119
120
121
# File 'lib/datadog/statsd/schema/namespace.rb', line 119

def metric_names
  metrics.keys
end

#metricsHash<Symbol, MetricDefinition>

Hash of metric definitions within this namespace

Since:

  • 0.1.0



45
# File 'lib/datadog/statsd/schema/namespace.rb', line 45

attribute :metrics, Types::Hash.map(Types::Symbol, MetricDefinition).default({}.freeze)

#nameSymbol

The namespace name as a symbol

Since:

  • 0.1.0



37
# File 'lib/datadog/statsd/schema/namespace.rb', line 37

attribute :name, Types::Strict::Symbol

#namespace_namesArray<Symbol>

Get all nested namespace names

Since:

  • 0.1.0



131
132
133
# File 'lib/datadog/statsd/schema/namespace.rb', line 131

def namespace_names
  namespaces.keys
end

#namespacesHash<Symbol, Namespace>

Hash of nested namespaces within this namespace

Since:

  • 0.1.0



49
# File 'lib/datadog/statsd/schema/namespace.rb', line 49

attribute :namespaces, Types::Hash.map(Types::Symbol, Namespace).default({}.freeze)

#tag_namesArray<Symbol>

Get all tag names in this namespace

Since:

  • 0.1.0



125
126
127
# File 'lib/datadog/statsd/schema/namespace.rb', line 125

def tag_names
  tags.keys
end

#tagsHash<Symbol, TagDefinition>

Hash of tag definitions within this namespace

Since:

  • 0.1.0



41
# File 'lib/datadog/statsd/schema/namespace.rb', line 41

attribute :tags, Types::Hash.map(Types::Symbol, TagDefinition).default({}.freeze)

#total_metrics_countInteger

Count total metrics including nested namespaces

Since:

  • 0.1.0



274
275
276
# File 'lib/datadog/statsd/schema/namespace.rb', line 274

def total_metrics_count
  metrics.count + namespaces.values.sum(&:total_metrics_count)
end

#total_namespaces_countInteger

Count total namespaces including nested

Since:

  • 0.1.0



280
281
282
# File 'lib/datadog/statsd/schema/namespace.rb', line 280

def total_namespaces_count
  namespaces.count + namespaces.values.sum(&:total_namespaces_count)
end

#validate_tag_referencesArray<String>

Validate that all tag references in metrics exist

Since:

  • 0.1.0



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/datadog/statsd/schema/namespace.rb', line 203

def validate_tag_references
  errors = []

  metrics.each do |metric_name, metric_def|
    # Check allowed tags
    metric_def.allowed_tags.each do |tag_name|
      errors << "Metric #{metric_name} references unknown tag: #{tag_name}" unless has_tag?(tag_name)
    end

    # Check required tags
    metric_def.required_tags.each do |tag_name|
      errors << "Metric #{metric_name} requires unknown tag: #{tag_name}" unless has_tag?(tag_name)
    end
  end

  # Validate nested namespaces recursively
  namespaces.each do |_, nested_namespace|
    errors.concat(nested_namespace.validate_tag_references)
  end

  errors
end