Class: PrometheusExporter::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/prometheus_exporter/client.rb

Direct Known Subclasses

LocalClient

Defined Under Namespace

Classes: RemoteMetric

Constant Summary collapse

MAX_SOCKET_AGE =
25
MAX_QUEUE_SIZE =
10_000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: ENV.fetch("PROMETHEUS_EXPORTER_HOST", "localhost"), port: ENV.fetch("PROMETHEUS_EXPORTER_PORT", PrometheusExporter::DEFAULT_PORT), max_queue_size: nil, thread_sleep: 0.5, json_serializer: nil, custom_labels: nil, logger: Logger.new(STDERR), log_level: Logger::WARN, process_queue_once_and_stop: false) ⇒ Client

Returns a new instance of Client.

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/prometheus_exporter/client.rb', line 54

def initialize(
  host: ENV.fetch("PROMETHEUS_EXPORTER_HOST", "localhost"),
  port: ENV.fetch("PROMETHEUS_EXPORTER_PORT", PrometheusExporter::DEFAULT_PORT),
  max_queue_size: nil,
  thread_sleep: 0.5,
  json_serializer: nil,
  custom_labels: nil,
  logger: Logger.new(STDERR),
  log_level: Logger::WARN,
  process_queue_once_and_stop: false
)
  @logger = logger
  @logger.level = log_level
  @metrics = []

  @queue = Queue.new

  @socket = nil
  @socket_started = nil
  @socket_pid = nil

  max_queue_size ||= MAX_QUEUE_SIZE
  max_queue_size = max_queue_size.to_i

  raise ArgumentError, "max_queue_size must be larger than 0" if max_queue_size <= 0

  @max_queue_size = max_queue_size
  @host = host
  @port = port
  @worker_thread = nil
  @mutex = Mutex.new
  @thread_sleep = thread_sleep

  @json_serializer = json_serializer == :oj ? PrometheusExporter::OjCompat : JSON

  @custom_labels = custom_labels
  @process_queue_once_and_stop = process_queue_once_and_stop
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



52
53
54
# File 'lib/prometheus_exporter/client.rb', line 52

def logger
  @logger
end

Class Method Details

.defaultObject



41
42
43
# File 'lib/prometheus_exporter/client.rb', line 41

def self.default
  @default ||= new
end

.default=(client) ⇒ Object



45
46
47
# File 'lib/prometheus_exporter/client.rb', line 45

def self.default=(client)
  @default = client
end

Instance Method Details

#custom_labels=(custom_labels) ⇒ Object



93
94
95
# File 'lib/prometheus_exporter/client.rb', line 93

def custom_labels=(custom_labels)
  @custom_labels = custom_labels
end

#find_registered_metric(name, type: nil, help: nil) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/prometheus_exporter/client.rb', line 103

def find_registered_metric(name, type: nil, help: nil)
  @metrics.find do |metric|
    type_match = type ? metric.type == type : true
    help_match = help ? metric.help == help : true
    name_match = metric.name == name

    type_match && help_match && name_match
  end
end

#process_queueObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/prometheus_exporter/client.rb', line 137

def process_queue
  while @queue.length > 0
    ensure_socket!

    begin
      message = @queue.pop
      @socket.write(message.bytesize.to_s(16).upcase)
      @socket.write("\r\n")
      @socket.write(message)
      @socket.write("\r\n")
    rescue => e
      logger.warn "Prometheus Exporter is dropping a message: #{e}"
      close_socket!
      raise
    end
  end
end

#register(type, name, help, opts = nil) ⇒ Object



97
98
99
100
101
# File 'lib/prometheus_exporter/client.rb', line 97

def register(type, name, help, opts = nil)
  metric = RemoteMetric.new(type: type, name: name, help: help, client: self, opts: opts)
  @metrics << metric
  metric
end

#send(str) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/prometheus_exporter/client.rb', line 127

def send(str)
  @queue << str
  if @queue.length > @max_queue_size
    logger.warn "Prometheus Exporter client is dropping message cause queue is full"
    @queue.pop
  end

  ensure_worker_thread!
end

#send_json(obj) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/prometheus_exporter/client.rb', line 113

def send_json(obj)
  payload =
    if @custom_labels
      if obj[:custom_labels]
        obj.merge(custom_labels: @custom_labels.merge(obj[:custom_labels]))
      else
        obj.merge(custom_labels: @custom_labels)
      end
    else
      obj
    end
  send(@json_serializer.dump(payload))
end

#stop(wait_timeout_seconds: 0) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'lib/prometheus_exporter/client.rb', line 155

def stop(wait_timeout_seconds: 0)
  @mutex.synchronize do
    wait_for_empty_queue_with_timeout(wait_timeout_seconds)
    @worker_thread&.kill
    sleep 0.001 while @worker_thread&.alive?
    @worker_thread = nil
    close_socket!
  end
end