Class: Statsig::StatsigLogger

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

Instance Method Summary collapse

Constructor Details

#initialize(network, options) ⇒ StatsigLogger

Returns a new instance of StatsigLogger.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/statsig_logger.rb', line 12

def initialize(network, options)
  @network = network
  @events = []
  @options = options

  @logging_pool = Concurrent::ThreadPoolExecutor.new(
    min_threads: [2, Concurrent.processor_count].min,
    max_threads: [2, Concurrent.processor_count].max,
    # max jobs pending before we start dropping
    max_queue:   [2, Concurrent.processor_count].max * 5,
    fallback_policy: :discard,
  )

  @background_flush = periodic_flush
end

Instance Method Details

#flushObject



121
122
123
124
125
126
127
128
129
130
# File 'lib/statsig_logger.rb', line 121

def flush
  if @events.length == 0
    return
  end
  events_clone = @events
  @events = []
  flush_events = events_clone.map { |e| e.serialize }

  @network.post_logs(flush_events)
end

#flush_asyncObject



115
116
117
118
119
# File 'lib/statsig_logger.rb', line 115

def flush_async
  @logging_pool.post do
    flush
  end
end

#log_config_exposure(user, config_name, rule_id, secondary_exposures, eval_details, context = nil) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/statsig_logger.rb', line 51

def log_config_exposure(user, config_name, rule_id, secondary_exposures, eval_details, context = nil)
  event = StatsigEvent.new($config_exposure_event)
  event.user = user
  event. = {
    'config' => config_name,
    'ruleID' => rule_id,
  }
  event. = Statsig.
  event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []

  safe_add_eval_details(eval_details, event)
  safe_add_exposure_context(context, event)
  log_event(event)
end

#log_diagnostics_event(diagnostics, user = nil) ⇒ Object



92
93
94
95
96
97
# File 'lib/statsig_logger.rb', line 92

def log_diagnostics_event(diagnostics, user = nil)
  event = StatsigEvent.new($diagnostics_event)
  event.user = user
  event. = diagnostics.serialize
  log_event(event)
end

#log_event(event) ⇒ Object



28
29
30
31
32
33
# File 'lib/statsig_logger.rb', line 28

def log_event(event)
  @events.push(event)
  if @events.length >= @options.logging_max_buffer_size
    flush_async
  end
end

#log_gate_exposure(user, gate_name, value, rule_id, secondary_exposures, eval_details, context = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/statsig_logger.rb', line 35

def log_gate_exposure(user, gate_name, value, rule_id, secondary_exposures, eval_details, context = nil)
  event = StatsigEvent.new($gate_exposure_event)
  event.user = user
  event. = {
    'gate' => gate_name,
    'gateValue' => value.to_s,
    'ruleID' => rule_id,
  }
  event. = Statsig.
  event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []

  safe_add_eval_details(eval_details, event)
  safe_add_exposure_context(context, event)
  log_event(event)
end

#log_layer_exposure(user, layer, parameter_name, config_evaluation, context = nil) ⇒ Object



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
# File 'lib/statsig_logger.rb', line 66

def log_layer_exposure(user, layer, parameter_name, config_evaluation, context = nil)
  exposures = config_evaluation.undelegated_sec_exps
  allocated_experiment = ''
  is_explicit = (config_evaluation.explicit_parameters&.include? parameter_name) || false
  if is_explicit
    allocated_experiment = config_evaluation.config_delegate
    exposures = config_evaluation.secondary_exposures
  end

  event = StatsigEvent.new($layer_exposure_event)
  event.user = user
  event. = {
    'config' => layer.name,
    'ruleID' => layer.rule_id,
    'allocatedExperiment' => allocated_experiment,
    'parameterName' => parameter_name,
    'isExplicitParameter' => String(is_explicit),
  }
  event. = Statsig.
  event.secondary_exposures = exposures.is_a?(Array) ? exposures : []

  safe_add_eval_details(config_evaluation.evaluation_details, event)
  safe_add_exposure_context(context, event)
  log_event(event)
end

#maybe_restart_background_threadsObject



132
133
134
135
136
# File 'lib/statsig_logger.rb', line 132

def maybe_restart_background_threads
  if @background_flush.nil? or !@background_flush.alive?
    @background_flush = periodic_flush
  end
end

#periodic_flushObject



99
100
101
102
103
104
105
106
# File 'lib/statsig_logger.rb', line 99

def periodic_flush
  Thread.new do
    loop do
      sleep @options.logging_interval_seconds
      flush
    end
  end
end

#shutdownObject



108
109
110
111
112
113
# File 'lib/statsig_logger.rb', line 108

def shutdown
  @background_flush&.exit
  @logging_pool.shutdown
  @logging_pool.wait_for_termination(timeout = 3)
  flush
end