Class: Datadog::Statsd::Emitter

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/datadog/statsd/emitter.rb

Overview

Since:

  • 0.1.0

Constant Summary collapse

MUTEX =

Since:

  • 0.1.0

Mutex.new
DEFAULT_HOST =

Since:

  • 0.1.0

"127.0.0.1"
DEFAULT_PORT =

Since:

  • 0.1.0

8125
DEFAULT_NAMESPACE =

Since:

  • 0.1.0

nil
DEFAULT_ARGUMENTS =

Since:

  • 0.1.0

{ delay_serialization: true }
DEFAULT_SAMPLE_RATE =

Since:

  • 0.1.0

1.0
DEFAULT_VALIDATION_MODE =

Since:

  • 0.1.0

:strict

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(emitter = nil, stderr: $stderr, metric: nil, tags: nil, ab_test: nil, sample_rate: nil, schema: nil, validation_mode: DEFAULT_VALIDATION_MODE) ⇒ Emitter

Returns a new instance of Emitter.

Parameters:

  • emitter (String, Symbol, Module, Class, Object) (defaults to: nil)

    The emitter identifier.

  • stderr (IO) (defaults to: $stderr)

    The stderr output stream. Defaults to $stderr.

  • metric (String) (defaults to: nil)

    The metric name (or prefix) to use for all metrics.

  • tags (Hash) (defaults to: nil)

    The tags to add to the metric.

  • ab_test (Hash) (defaults to: nil)

    The AB test to add to the metric.

  • sample_rate (Float) (defaults to: nil)

    The sample rate to use for the metric.

  • schema (Schema) (defaults to: nil)

    The schema to use for validation.

  • validation_mode (Symbol) (defaults to: DEFAULT_VALIDATION_MODE)

    The validation mode to use. Defaults to :strict. :strict - Raises an error if the metric is invalid. :warn - Logs a warning if the metric is invalid. :drop - Drops the metric if it is invalid. :off - Disables validation.

Since:

  • 0.1.0



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/datadog/statsd/emitter.rb', line 176

def initialize(
  emitter = nil,
  stderr: $stderr,
  metric: nil,
  tags: nil,
  ab_test: nil,
  sample_rate: nil,
  schema: nil,
  validation_mode: DEFAULT_VALIDATION_MODE
)
  if emitter.nil? && metric.nil? && tags.nil? && ab_test.nil? && sample_rate.nil? && schema.nil?
    raise ArgumentError,
          "Datadog::Statsd::Emitter: use class methods if you are passing nothing to the constructor."
  end
  @sample_rate = sample_rate || 1.0

  # Initialize tags with provided tags or empty hash
  @tags = (tags || {}).dup

  # Merge global tags from Schema configuration
  schema_global_tags = ::Datadog::Statsd::Schema.configuration.tags || {}
  @tags.merge!(schema_global_tags)

  # Merge global tags from Emitter configuration
  emitter_global_tags = self.class.global_tags.to_h
  @tags.merge!(emitter_global_tags)

  @ab_test = ab_test || {}
  @metric = metric
  @schema = schema
  @validation_mode = validation_mode
  @stderr = stderr

  emitter =
    case emitter
    when String, Symbol
      emitter.to_s
    when Module, Class
      emitter.name
    else
      emitter&.class&.name
    end

  emitter = nil if emitter == "Object"
  emitter = emitter&.gsub("::", ".")&.underscore&.downcase

  return unless emitter

  @tags[:emitter] = emitter
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, **opts) ⇒ Object

Since:

  • 0.1.0



227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/datadog/statsd/emitter.rb', line 227

def method_missing(m, *args, **opts, &)
  args, opts = normalize_arguments(*args, **opts)

  # If schema validation fails, handle based on validation mode
  if @schema && should_validate?(args)
    validation_result = validate_metric_call(m, *args, **opts)
    return if validation_result == :drop
  end

  if ENV.fetch("DATADOG_DEBUG", false)
    warn "<CUSTOM METRIC to STATSD>: #{self}->#{m}(#{args.join(", ")}, #{opts.inspect})"
  end
  statsd&.send(m, *args, **opts, &)
end

Class Attribute Details

.datadog_statsdObject

Since:

  • 0.1.0



43
44
45
# File 'lib/datadog/statsd/emitter.rb', line 43

def datadog_statsd
  @datadog_statsd
end

Instance Attribute Details

#ab_testObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def ab_test
  @ab_test
end

#metricObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def metric
  @metric
end

#sample_rateObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def sample_rate
  @sample_rate
end

#schemaObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def schema
  @schema
end

#stderrObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def stderr
  @stderr
end

#tagsObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def tags
  @tags
end

#validation_modeObject (readonly)

Since:

  • 0.1.0



161
162
163
# File 'lib/datadog/statsd/emitter.rb', line 161

def validation_mode
  @validation_mode
end

Class Method Details

.configure {|global_tags| ... } ⇒ Object

Yields:

Since:

  • 0.1.0



85
86
87
# File 'lib/datadog/statsd/emitter.rb', line 85

def configure
  yield(global_tags)
end

.decrement(*args, **opts) ⇒ Object

Since:

  • 0.1.0



61
62
63
# File 'lib/datadog/statsd/emitter.rb', line 61

def decrement(*args, **opts)
  send_metric_with_global_tags(:decrement, *args, **opts)
end

.distribution(*args, **opts) ⇒ Object

Since:

  • 0.1.0



73
74
75
# File 'lib/datadog/statsd/emitter.rb', line 73

def distribution(*args, **opts)
  send_metric_with_global_tags(:distribution, *args, **opts)
end

.gauge(*args, **opts) ⇒ Object

Since:

  • 0.1.0



65
66
67
# File 'lib/datadog/statsd/emitter.rb', line 65

def gauge(*args, **opts)
  send_metric_with_global_tags(:gauge, *args, **opts)
end

.global_tagsObject

Since:

  • 0.1.0



81
82
83
# File 'lib/datadog/statsd/emitter.rb', line 81

def global_tags
  @global_tags ||= OpenStruct.new
end

.histogram(*args, **opts) ⇒ Object

Since:

  • 0.1.0



69
70
71
# File 'lib/datadog/statsd/emitter.rb', line 69

def histogram(*args, **opts)
  send_metric_with_global_tags(:histogram, *args, **opts)
end

.increment(*args, **opts) ⇒ Object

Override metric methods to ensure global tags are applied

Since:

  • 0.1.0



57
58
59
# File 'lib/datadog/statsd/emitter.rb', line 57

def increment(*args, **opts)
  send_metric_with_global_tags(:increment, *args, **opts)
end

.set(*args, **opts) ⇒ Object

Since:

  • 0.1.0



77
78
79
# File 'lib/datadog/statsd/emitter.rb', line 77

def set(*args, **opts)
  send_metric_with_global_tags(:set, *args, **opts)
end

.statsdDatadog::Statsd, NilClass

Returns The Datadog Statsd client instance or nil if not currently connected.

Returns:

  • (Datadog::Statsd, NilClass)

    The Datadog Statsd client instance or nil if not currently connected.

Since:

  • 0.1.0



47
48
49
50
51
# File 'lib/datadog/statsd/emitter.rb', line 47

def statsd
  return @datadog_statsd if defined?(@datadog_statsd)

  @datadog_statsd = ::Datadog::Statsd::Schema.configuration.statsd
end

Instance Method Details

#normalize_arguments(*args, **opts) ⇒ Object

Since:

  • 0.1.0



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/datadog/statsd/emitter.rb', line 246

def normalize_arguments(*args, **opts)
  # Handle metric name - use constructor metric if none provided in method call
  normalized_args = args.dup

  if @metric
    if normalized_args.empty?
      normalized_args = [@metric]
    elsif normalized_args.first.nil?
      normalized_args[0] = @metric
    end
  end

  # Start with instance tags
  merged_tags = (@tags || {}).dup

  # Convert instance ab_test to tags
  (@ab_test || {}).each do |test_name, group|
    merged_tags[:ab_test_name] = test_name
    merged_tags[:ab_test_group] = group
  end

  # Handle ab_test from method call opts and remove it from opts
  normalized_opts = opts.dup
  if normalized_opts[:ab_test]
    normalized_opts[:ab_test].each do |test_name, group|
      merged_tags[:ab_test_name] = test_name
      merged_tags[:ab_test_group] = group
    end
    normalized_opts.delete(:ab_test)
  end

  # Merge with method call tags (method call tags take precedence)
  merged_tags = merged_tags.merge(normalized_opts[:tags]) if normalized_opts[:tags]

  # Set merged tags in opts if there are any
  normalized_opts[:tags] = merged_tags unless merged_tags.empty?

  # Handle sample_rate - use instance sample_rate if not provided in method call
  if @sample_rate && @sample_rate != 1.0 && !normalized_opts.key?(:sample_rate)
    normalized_opts[:sample_rate] = @sample_rate
  end

  [normalized_args, normalized_opts]
end

#respond_to_missing?(method) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



242
243
244
# File 'lib/datadog/statsd/emitter.rb', line 242

def respond_to_missing?(method, *)
  statsd&.respond_to? method
end