Class: Statsig::StatsigLogger
- Inherits:
-
Object
- Object
- Statsig::StatsigLogger
- Defined in:
- lib/statsig_logger.rb
Instance Method Summary collapse
- #flush ⇒ Object
- #flush_async ⇒ Object
-
#initialize(network, options, error_boundary) ⇒ StatsigLogger
constructor
A new instance of StatsigLogger.
- #log_config_exposure(user, config_name, rule_id, secondary_exposures, eval_details, context = nil) ⇒ Object
- #log_diagnostics_event(diagnostics, user = nil) ⇒ Object
- #log_event(event) ⇒ Object
- #log_gate_exposure(user, gate_name, value, rule_id, secondary_exposures, eval_details, context = nil) ⇒ Object
- #log_layer_exposure(user, layer, parameter_name, config_evaluation, context = nil) ⇒ Object
- #maybe_restart_background_threads ⇒ Object
- #periodic_flush ⇒ Object
- #shutdown ⇒ Object
Constructor Details
#initialize(network, options, error_boundary) ⇒ StatsigLogger
Returns a new instance of StatsigLogger.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/statsig_logger.rb', line 12 def initialize(network, , error_boundary) @network = network @events = [] @options = @logging_pool = Concurrent::ThreadPoolExecutor.new( name: 'statsig-logger', min_threads: @options.logger_threadpool_size, max_threads: @options.logger_threadpool_size, # max jobs pending before we start dropping max_queue: 100, fallback_policy: :discard ) @error_boundary = error_boundary @background_flush = periodic_flush @deduper = Concurrent::Set.new() @interval = 0 @flush_mutex = Mutex.new end |
Instance Method Details
#flush ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/statsig_logger.rb', line 138 def flush @flush_mutex.synchronize do if @events.length.zero? return end events_clone = @events @events = [] flush_events = events_clone.map { |e| e.serialize } @network.post_logs(flush_events) end end |
#flush_async ⇒ Object
132 133 134 135 136 |
# File 'lib/statsig_logger.rb', line 132 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
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/statsig_logger.rb', line 58 def log_config_exposure(user, config_name, rule_id, secondary_exposures, eval_details, context = nil) event = StatsigEvent.new($config_exposure_event) event.user = user = { 'config' => config_name, 'ruleID' => rule_id, } return false if not is_unique_exposure(user, $config_exposure_event, ) event. = 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
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/statsig_logger.rb', line 101 def log_diagnostics_event(diagnostics, user = nil) return if @options.disable_diagnostics_logging return if diagnostics.nil? || diagnostics.markers.empty? event = StatsigEvent.new($diagnostics_event) event.user = user event. = diagnostics.serialize log_event(event) diagnostics.clear_markers end |
#log_event(event) ⇒ Object
33 34 35 36 37 38 |
# File 'lib/statsig_logger.rb', line 33 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
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/statsig_logger.rb', line 40 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 = { 'gate' => gate_name, 'gateValue' => value.to_s, 'ruleID' => rule_id, } return false if not is_unique_exposure(user, $gate_exposure_event, ) event. = 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
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 |
# File 'lib/statsig_logger.rb', line 74 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 = { 'config' => layer.name, 'ruleID' => layer.rule_id, 'allocatedExperiment' => allocated_experiment, 'parameterName' => parameter_name, 'isExplicitParameter' => String(is_explicit), } return false if not is_unique_exposure(user, $layer_exposure_event, ) event. = 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_threads ⇒ Object
151 152 153 154 155 |
# File 'lib/statsig_logger.rb', line 151 def maybe_restart_background_threads if @background_flush.nil? || !@background_flush.alive? @background_flush = periodic_flush end end |
#periodic_flush ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/statsig_logger.rb', line 112 def periodic_flush Thread.new do @error_boundary.capture(task: lambda { loop do sleep @options.logging_interval_seconds flush_async @interval += 1 @deduper.clear if @interval % 2 == 0 end }) end end |
#shutdown ⇒ Object
125 126 127 128 129 130 |
# File 'lib/statsig_logger.rb', line 125 def shutdown @background_flush&.exit @logging_pool.shutdown @logging_pool.wait_for_termination(timeout = 3) flush end |