Class: Libhoney::Client

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

Overview

This is a library to allow you to send events to Honeycomb from within your Ruby application.

Examples:

Send a simple event

require 'libhoney'
honey = Libhoney.new(writekey, dataset, sample_rate)

evt = honey.event
evt.add(pglatency: 100)
honey.send(evt)

# repeat creating and sending events until your program is finished

honey.close

Override the default timestamp on an event

one_hour_ago = Time.now - 3600

evt = libhoney.event
evt.add_fields(useful_fields)
evt.timestamp = one_hour_ago
evt.send

Direct Known Subclasses

LogClient, NullClient, TestClient

Constant Summary collapse

API_HOST =
'https://api.honeycomb.io/'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(writekey: nil, dataset: nil, sample_rate: 1, api_host: API_HOST, user_agent_addition: nil, transmission: nil, block_on_send: false, block_on_responses: false, max_batch_size: 50, send_frequency: 100, max_concurrent_batches: 10, pending_work_capacity: 1000, proxy_config: nil) ⇒ Client

Instantiates libhoney and prepares it to send events to Honeycomb.

rubocop:disable Metrics/ParameterLists

Parameters:

  • writekey (String) (defaults to: nil)

    the Honeycomb API key with which to authenticate this request (required)

  • dataset (String) (defaults to: nil)

    the Honeycomb dataset into which to send events (required)

  • sample_rate (Fixnum) (defaults to: 1)

    cause libhoney to send 1 out of sample_rate events. overrides the libhoney instance’s value. (e.g. setting this to 10 will result in a 1-in-10 chance of it being successfully emitted to Honeycomb, and the Honeycomb query engine will interpret it as representative of 10 events)

  • api_host (String) (defaults to: API_HOST)

    defaults to API_HOST, override to change the destination for these Honeycomb events.

  • transmission (Object) (defaults to: nil)

    transport used to actually send events. If nil (the default), will be lazily initialized with a TransmissionClient on first event send.

  • block_on_send (Boolean) (defaults to: false)

    if more than pending_work_capacity events are written, block sending further events

  • block_on_responses (Boolean) (defaults to: false)

    if true, block if there is no thread reading from the response queue

  • pending_work_capacity (Fixnum) (defaults to: 1000)

    defaults to 1000. If the queue of pending events exceeds 1000, this client will start dropping events.

Raises:

  • (Exception)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/libhoney/client.rb', line 74

def initialize(writekey: nil,
               dataset: nil,
               sample_rate: 1,
               api_host: API_HOST,
               user_agent_addition: nil,
               transmission: nil,
               block_on_send: false,
               block_on_responses: false,
               max_batch_size: 50,
               send_frequency: 100,
               max_concurrent_batches: 10,
               pending_work_capacity: 1000,
               proxy_config: nil)
  # rubocop:enable Metrics/ParameterLists
  # check for insanity
  raise Exception, 'libhoney:  max_concurrent_batches must be greater than 0' if max_concurrent_batches < 1
  raise Exception, 'libhoney:  sample rate must be greater than 0'            if sample_rate < 1

  unless Gem::Dependency.new('ruby', '~> 2.2').match?('ruby', RUBY_VERSION)
    raise Exception, 'libhoney:  Ruby versions < 2.2 are not supported'
  end

  @builder = Builder.new(self, nil)

  @builder.writekey    = writekey
  @builder.dataset     = dataset
  @builder.sample_rate = sample_rate
  @builder.api_host    = api_host

  @transmission = transmission
  if !@transmission && !(writekey && dataset)
    # if no writekey or dataset are configured, and we didn't override the
    # transmission (e.g. to a MockTransmissionClient), that's almost
    # certainly a misconfiguration, even though it's possible to override
    # them on a per-event basis. So let's handle the misconfiguration
    # early rather than potentially throwing thousands of exceptions at runtime.
    warn "#{self.class.name}: no #{writekey ? 'dataset' : 'writekey'} configured, disabling sending events"
    @transmission = NullTransmissionClient.new
  end

  @user_agent_addition = user_agent_addition

  @block_on_send          = block_on_send
  @block_on_responses     = block_on_responses
  @max_batch_size         = max_batch_size
  @send_frequency         = send_frequency
  @max_concurrent_batches = max_concurrent_batches
  @pending_work_capacity  = pending_work_capacity
  @responses              = SizedQueue.new(2 * @pending_work_capacity)
  @lock                   = Mutex.new
  @proxy_config           = proxy_config
end

Instance Attribute Details

#block_on_responsesObject (readonly)

Returns the value of attribute block_on_responses.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def block_on_responses
  @block_on_responses
end

#block_on_sendObject (readonly)

Returns the value of attribute block_on_send.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def block_on_send
  @block_on_send
end

#max_batch_sizeObject (readonly)

Returns the value of attribute max_batch_size.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def max_batch_size
  @max_batch_size
end

#max_concurrent_batchesObject (readonly)

Returns the value of attribute max_concurrent_batches.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def max_concurrent_batches
  @max_concurrent_batches
end

#pending_work_capacityObject (readonly)

Returns the value of attribute pending_work_capacity.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def pending_work_capacity
  @pending_work_capacity
end

#responsesObject (readonly)

Returns the value of attribute responses.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def responses
  @responses
end

#send_frequencyObject (readonly)

Returns the value of attribute send_frequency.



129
130
131
# File 'lib/libhoney/client.rb', line 129

def send_frequency
  @send_frequency
end

Instance Method Details

#add(data) ⇒ self

adds a group of field->values to the global Builder.

Examples:

honey.add {
  :responseTime_ms => 100,
  :httpStatusCode => 200
}

Parameters:

  • data (Hash<String=>any>)

    field->value mapping.

Returns:

  • (self)

    this Client instance



158
159
160
161
# File 'lib/libhoney/client.rb', line 158

def add(data)
  @builder.add(data)
  self
end

#add_dynamic_field(name, proc) ⇒ self

adds a single field->dynamic value function to the global Builder.

Examples:

honey.add_dynamic_field("active_threads", Proc.new { Thread.list.select {|thread| thread.status == "run"}.count })

Parameters:

  • name (String)

    name of field to add.

  • proc (#call)

    function that will be called to generate the value whenever an event is created.

Returns:

  • (self)

    this libhoney instance.



182
183
184
185
# File 'lib/libhoney/client.rb', line 182

def add_dynamic_field(name, proc)
  @builder.add_dynamic_field(name, proc)
  self
end

#add_field(name, val) ⇒ self

adds a single field->value mapping to the global Builder.

Examples:

honey.add_field("responseTime_ms", 100)

Parameters:

  • name (String)

    name of field to add.

  • val (any)

    value of field to add.

Returns:

  • (self)

    this Client instance



170
171
172
173
# File 'lib/libhoney/client.rb', line 170

def add_field(name, val)
  @builder.add_field(name, val)
  self
end

#builder(fields = {}, dyn_fields = {}) ⇒ Object



137
138
139
# File 'lib/libhoney/client.rb', line 137

def builder(fields = {}, dyn_fields = {})
  @builder.builder(fields, dyn_fields)
end

#close(drain = true) ⇒ Object

Nuke the queue and wait for inflight requests to complete before returning. If you set drain=false, all queued requests will be dropped on the floor.



143
144
145
146
147
# File 'lib/libhoney/client.rb', line 143

def close(drain = true)
  return @transmission.close(drain) if @transmission

  0
end

#eventObject



133
134
135
# File 'lib/libhoney/client.rb', line 133

def event
  @builder.event
end

#send_dropped_response(event, msg) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



239
240
241
242
243
244
245
246
247
# File 'lib/libhoney/client.rb', line 239

def send_dropped_response(event, msg)
  response = Response.new(error: msg,
                          metadata: event.)
  begin
    @responses.enq(response, !@block_on_responses)
  rescue ThreadError
    # happens if the queue was full and block_on_responses = false.
  end
end

#send_event(event) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Enqueue an event to send. Sampling happens here, and we will create new threads to handle work as long as we haven’t gone over max_concurrent_batches and there are still events in the queue.

Parameters:

  • event (Event)

    the event to send to honeycomb



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/libhoney/client.rb', line 218

def send_event(event)
  @lock.synchronize do
    transmission_client_params = {
      max_batch_size: @max_batch_size,
      send_frequency: @send_frequency,
      max_concurrent_batches: @max_concurrent_batches,
      pending_work_capacity: @pending_work_capacity,
      responses: @responses,
      block_on_send: @block_on_send,
      block_on_responses: @block_on_responses,
      user_agent_addition: @user_agent_addition,
      proxy_config: @proxy_config
    }

    @transmission ||= TransmissionClient.new(**transmission_client_params)
  end

  @transmission.add(event)
end

#send_now(data = {}) ⇒ self

Deprecated.

Creates and sends an event, including all global builder fields/dyn_fields, as well as anything in the optional data parameter.

Equivalent to:

ev = builder.event
ev.add(data)
ev.send

May be removed in a future major release

/

Examples:

empty send_now

honey.send_now # sends just the data that has been added via add/add_field/add_dynamic_field.

adding data at send-time

honey.send_now {
  additionalField: value
}

Parameters:

  • data (Hash<String=>any>) (defaults to: {})

    optional field->value mapping to add to the event sent.

Returns:

  • (self)

    this libhoney instance.



206
207
208
209
# File 'lib/libhoney/client.rb', line 206

def send_now(data = {})
  @builder.send_now(data)
  self
end

#should_drop(sample_rate) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



250
251
252
# File 'lib/libhoney/client.rb', line 250

def should_drop(sample_rate)
  rand(1..sample_rate) != 1
end