Module: OpenObserve::Coerce

Defined in:
lib/openobserve/coerce.rb

Overview

OpenObserve expresses every timestamp in microseconds since the epoch — a unit no Ruby time type produces naturally, and the single most likely thing for a caller to get wrong by three or six orders of magnitude. This absorbs that quirk: domains take Time, Date, String or epoch seconds and hand microseconds to the transport.

Constant Summary collapse

PER_SECOND =

Microseconds in one second.

1_000_000

Class Method Summary collapse

Class Method Details

.as_time(value) ⇒ Time

Parameters:

  • value (Time, DateTime, Date, String)

Returns:

  • (Time)

Raises:



36
37
38
39
40
41
42
43
44
45
# File 'lib/openobserve/coerce.rb', line 36

def as_time(value)
  case value
  when Time     then value
  when DateTime then value.to_time
  when Date     then Time.new(value.year, value.month, value.day)
  when String   then Time.parse(value)
  else
    raise Client::Error, "cannot read #{value.class} as a point in time"
  end
end

.micros(value) ⇒ Integer?

Convert a point in time to microseconds since the epoch.

A Numeric is read as epoch seconds, matching Time#to_i — never as microseconds, so a value that is already converted is never silently accepted twice.

Parameters:

  • value (Time, DateTime, Date, String, Numeric, nil)

Returns:

  • (Integer, nil)

    microseconds, or nil when value is nil

Raises:



25
26
27
28
29
30
31
# File 'lib/openobserve/coerce.rb', line 25

def micros(value)
  case value
  when nil     then nil
  when Numeric then (value * PER_SECOND).round
  else (as_time(value).to_r * PER_SECOND).round
  end
end

.window(from: nil, to: nil, last: nil, now: Time.now) ⇒ Array(Integer, Integer)

Build the [start_time, end_time] microsecond pair every search takes.

Parameters:

  • from (Time, Date, String, Numeric, nil) (defaults to: nil)

    lower bound

  • to (Time, Date, String, Numeric, nil) (defaults to: nil)

    upper bound; defaults to now

  • last (Numeric, nil) (defaults to: nil)

    trailing window length in seconds, e.g. 3600

  • now (Time) (defaults to: Time.now)

    reference for last and for the default upper bound; injectable so specs need no clock stubbing

Returns:

  • (Array(Integer, Integer))

Raises:

  • (OpenObserve::Client::Error)

    when no lower bound is given, or the window is inverted (which the server would answer with an empty, and very puzzling, result)



57
58
59
60
61
62
63
64
65
# File 'lib/openobserve/coerce.rb', line 57

def window(from: nil, to: nil, last: nil, now: Time.now)
  end_time   = micros(to) || micros(now)
  start_time = micros(from) || (last && (end_time - (last * PER_SECOND).round))

  raise Client::Error, 'a search needs a lower bound: pass from: or last:' if start_time.nil?
  raise Client::Error, 'the window start must be before its end' if start_time >= end_time

  [start_time, end_time]
end