Module: Vivarium

Defined in:
lib/vivarium.rb,
lib/vivarium/logger.rb,
lib/vivarium/version.rb

Defined Under Namespace

Classes: Daemon, Error, Event, Logger, MapStore, ObservationSession

Constant Summary collapse

PIN_DIR =
ENV.fetch("VIVARIUM_BPF_PIN_DIR", "/sys/fs/bpf/vivarium")
CONFIG_ROOT_TARGETS_PIN =
File.join(PIN_DIR, "config_root_targets")
CONFIG_SPAWNED_TARGETS_PIN =
File.join(PIN_DIR, "config_spawned_targets")
CONFIG_TARGETS_PIN =
CONFIG_ROOT_TARGETS_PIN
EVENT_INVOKED_PIN =
File.join(PIN_DIR, "event_invoked")
EVENT_WRITE_POS_PIN =
File.join(PIN_DIR, "event_write_pos")
EVENT_NAME_SIZE =
16
EVENT_PAYLOAD_SIZE =
256
EVENT_STRUCT_SIZE =
4 + EVENT_NAME_SIZE + EVENT_PAYLOAD_SIZE
EVENT_CAPACITY =
64
VERSION =
"0.1.1"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.bpf_pin_dirObject



31
32
33
# File 'lib/vivarium.rb', line 31

def bpf_pin_dir
  @bpf_pin_dir || PIN_DIR
end

Class Method Details

.build_observe_tracepoint(store, logger) ⇒ Object



436
437
438
439
440
441
442
443
444
445
# File 'lib/vivarium.rb', line 436

def self.build_observe_tracepoint(store, logger)
  TracePoint.new(:return, :c_return) do |tp|
    events = store.drain_events
    next if events.empty?

    stack = caller_locations(2, 16)
    stack = stack.reject { |loc| loc.path.to_s.include?("vivarium") } if filter_internal_frames?
    logger.log(events, tp, stack)
  end
end

.filter_internal_frames?Boolean

Returns:

  • (Boolean)


447
448
449
450
451
452
# File 'lib/vivarium.rb', line 447

def self.filter_internal_frames?
  value = ENV["VIVARIUM_FILTER_INTERNAL_FRAMES"]
  return true if value.nil?

  !%w[0 false off no].include?(value.strip.downcase)
end

.observe(pin_dir: bpf_pin_dir, logger: nil, dest: $stdout, format: :human) ⇒ Object



399
400
401
402
403
# File 'lib/vivarium.rb', line 399

def self.observe(pin_dir: bpf_pin_dir, logger: nil, dest: $stdout, format: :human)
  return scoped_observe(pin_dir: pin_dir, logger: logger, dest: dest, format: format) { yield } if block_given?

  top_observe(pin_dir: pin_dir, logger: logger, dest: dest, format: format)
end

.run_daemon!(argv = ARGV) ⇒ Object



454
455
456
457
458
459
460
461
462
# File 'lib/vivarium.rb', line 454

def self.run_daemon!(argv = ARGV)
  options = { pin_dir: bpf_pin_dir }
  OptionParser.new do |opts|
    opts.banner = "Usage: vivariumd [--pin-dir PATH]"
    opts.on("--pin-dir PATH", "Pinned map directory") { |v| options[:pin_dir] = v }
  end.parse!(argv)

  Daemon.new(pin_dir: options[:pin_dir]).run
end

.scoped_observe(pin_dir:, logger:, dest:, format:) ⇒ Object



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/vivarium.rb', line 420

def self.scoped_observe(pin_dir:, logger:, dest:, format:)
  logger ||= Logger.new(dest: dest, format: format)
  store = MapStore.new(pin_dir: pin_dir)
  pid = Process.pid
  store.register_pid(pid)
  logger.info("scoped observing with pid=#{pid}")

  tracer = build_observe_tracepoint(store, logger)
  tracer.enable

  yield
ensure
  tracer&.disable
  store&.unregister_pid(pid)
end

.top_observe(pin_dir: bpf_pin_dir, logger: nil, dest: $stdout, format: :human) ⇒ Object



405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/vivarium.rb', line 405

def self.top_observe(pin_dir: bpf_pin_dir, logger: nil, dest: $stdout, format: :human)
  logger ||= Logger.new(dest: dest, format: format)
  store = MapStore.new(pin_dir: pin_dir)
  pid = Process.pid
  store.register_pid(pid)
  logger.info("top-level observing with pid=#{pid}")

  tracer = build_observe_tracepoint(store, logger)
  tracer.enable

  session = ObservationSession.new(store: store, pid: pid, tracer: tracer)
  at_exit { session.stop }
  session
end