prefab-cloud-ruby 0.24.3 → 0.24.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +76 -0
- data/Gemfile.lock +4 -4
- data/VERSION +1 -1
- data/bin/console +21 -0
- data/compile_protos.sh +6 -0
- data/lib/prefab/client.rb +25 -4
- data/lib/prefab/config_client.rb +16 -6
- data/lib/prefab/config_loader.rb +1 -1
- data/lib/prefab/config_resolver.rb +2 -4
- data/lib/prefab/config_value_wrapper.rb +18 -0
- data/lib/prefab/context.rb +22 -2
- data/lib/prefab/context_shape.rb +20 -0
- data/lib/prefab/context_shape_aggregator.rb +63 -0
- data/lib/prefab/criteria_evaluator.rb +61 -41
- data/lib/prefab/evaluated_configs_aggregator.rb +60 -0
- data/lib/prefab/evaluated_keys_aggregator.rb +41 -0
- data/lib/prefab/local_config_parser.rb +13 -13
- data/lib/prefab/log_path_aggregator.rb +64 -0
- data/lib/prefab/logger_client.rb +11 -13
- data/lib/prefab/options.rb +37 -1
- data/lib/prefab/periodic_sync.rb +51 -0
- data/lib/prefab/time_helpers.rb +7 -0
- data/lib/prefab-cloud-ruby.rb +8 -1
- data/lib/prefab_pb.rb +33 -220
- data/prefab-cloud-ruby.gemspec +21 -5
- data/test/test_config_loader.rb +15 -15
- data/test/test_config_resolver.rb +102 -102
- data/test/test_config_value_unwrapper.rb +13 -13
- data/test/test_context.rb +42 -0
- data/test/test_context_shape.rb +51 -0
- data/test/test_context_shape_aggregator.rb +137 -0
- data/test/test_criteria_evaluator.rb +253 -150
- data/test/test_evaluated_configs_aggregator.rb +254 -0
- data/test/test_evaluated_keys_aggregator.rb +54 -0
- data/test/test_helper.rb +34 -2
- data/test/test_log_path_aggregator.rb +57 -0
- data/test/test_logger.rb +33 -33
- data/test/test_weighted_value_resolver.rb +2 -2
- metadata +21 -5
- data/lib/prefab/log_path_collector.rb +0 -102
- data/test/test_log_path_collector.rb +0 -58
| @@ -1,102 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Prefab
         | 
| 4 | 
            -
              class LogPathCollector
         | 
| 5 | 
            -
                INCREMENT = ->(count) { (count || 0) + 1 }
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                SEVERITY_KEY = {
         | 
| 8 | 
            -
                  ::Logger::DEBUG => 'debugs',
         | 
| 9 | 
            -
                  ::Logger::INFO => 'infos',
         | 
| 10 | 
            -
                  ::Logger::WARN => 'warns',
         | 
| 11 | 
            -
                  ::Logger::ERROR => 'errors',
         | 
| 12 | 
            -
                  ::Logger::FATAL => 'fatals'
         | 
| 13 | 
            -
                }.freeze
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def initialize(client:, max_paths:, sync_interval:)
         | 
| 16 | 
            -
                  @max_paths = max_paths
         | 
| 17 | 
            -
                  @client = client
         | 
| 18 | 
            -
                  @start_at = now
         | 
| 19 | 
            -
                  @sync_interval = if sync_interval.is_a?(Numeric)
         | 
| 20 | 
            -
                                     proc { sync_interval }
         | 
| 21 | 
            -
                                   else
         | 
| 22 | 
            -
                                     sync_interval || ExponentialBackoff.new(initial_delay: 8, max_delay: 60 * 10)
         | 
| 23 | 
            -
                                   end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  @pool = Concurrent::ThreadPoolExecutor.new(
         | 
| 26 | 
            -
                    fallback_policy: :discard,
         | 
| 27 | 
            -
                    max_queue: 5,
         | 
| 28 | 
            -
                    max_threads: 4,
         | 
| 29 | 
            -
                    min_threads: 1,
         | 
| 30 | 
            -
                    name: 'prefab-log-paths'
         | 
| 31 | 
            -
                  )
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                  @paths = Concurrent::Map.new
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  start_periodic_sync
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                def push(path, severity)
         | 
| 39 | 
            -
                  return unless @paths.size < @max_paths
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  @paths.compute([path, severity], &INCREMENT)
         | 
| 42 | 
            -
                end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                private
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                def sync
         | 
| 47 | 
            -
                  return if @paths.size.zero?
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  log_internal "Syncing #{@paths.size} paths"
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  flush
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                def flush
         | 
| 55 | 
            -
                  to_ship = @paths.dup
         | 
| 56 | 
            -
                  @paths.clear
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                  start_at_was = @start_at
         | 
| 59 | 
            -
                  @start_at = now
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  @pool.post do
         | 
| 62 | 
            -
                    log_internal "Uploading stats for #{to_ship.size} paths"
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                    aggregate = Hash.new { |h, k| h[k] = Prefab::Logger.new }
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                    to_ship.each do |(path, severity), count|
         | 
| 67 | 
            -
                      aggregate[path][SEVERITY_KEY[severity]] = count
         | 
| 68 | 
            -
                      aggregate[path]['logger_name'] = path
         | 
| 69 | 
            -
                    end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                    loggers = Prefab::Loggers.new(
         | 
| 72 | 
            -
                      loggers: aggregate.values,
         | 
| 73 | 
            -
                      start_at: start_at_was,
         | 
| 74 | 
            -
                      end_at: now,
         | 
| 75 | 
            -
                      instance_hash: @client.instance_hash,
         | 
| 76 | 
            -
                      namespace: @client.namespace
         | 
| 77 | 
            -
                    )
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                    @client.post('/api/v1/known-loggers', loggers)
         | 
| 80 | 
            -
                  end
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                def start_periodic_sync
         | 
| 84 | 
            -
                  Thread.new do
         | 
| 85 | 
            -
                    log_internal "Initialized log path collector instance_hash=#{@client.instance_hash} max_paths=#{@max_paths}"
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                    loop do
         | 
| 88 | 
            -
                      sleep @sync_interval.call
         | 
| 89 | 
            -
                      sync
         | 
| 90 | 
            -
                    end
         | 
| 91 | 
            -
                  end
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                def log_internal(message)
         | 
| 95 | 
            -
                  @client.log.log_internal message, 'log_path_collector', nil, ::Logger::DEBUG
         | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                def now
         | 
| 99 | 
            -
                  (Time.now.utc.to_f * 1000).to_i
         | 
| 100 | 
            -
                end
         | 
| 101 | 
            -
              end
         | 
| 102 | 
            -
            end
         | 
| @@ -1,58 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'test_helper'
         | 
| 4 | 
            -
            require 'timecop'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            class TestLogPathCollector < Minitest::Test
         | 
| 7 | 
            -
              MAX_WAIT = 2
         | 
| 8 | 
            -
              SLEEP_TIME = 0.01
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              def test_sync
         | 
| 11 | 
            -
                Timecop.freeze do
         | 
| 12 | 
            -
                  client = new_client(namespace: 'this.is.a.namespace')
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  2.times { client.log.info('here is a message') }
         | 
| 15 | 
            -
                  3.times { client.log.error('here is a message') }
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  requests = []
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  client.define_singleton_method(:post) do |*params|
         | 
| 20 | 
            -
                    requests.push(params)
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  client.log_path_collector.send(:sync)
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  # let the flush thread run
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  wait_time = 0
         | 
| 28 | 
            -
                  while requests.length == 0
         | 
| 29 | 
            -
                    wait_time += SLEEP_TIME
         | 
| 30 | 
            -
                    sleep SLEEP_TIME
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                    raise "Waited #{MAX_WAIT} seconds for the flush thread to run, but it never did" if wait_time > MAX_WAIT
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  assert_equal requests, [[
         | 
| 36 | 
            -
                    '/api/v1/known-loggers',
         | 
| 37 | 
            -
                    Prefab::Loggers.new(
         | 
| 38 | 
            -
                      loggers: [Prefab::Logger.new(logger_name: 'test.test_log_path_collector.test_sync',
         | 
| 39 | 
            -
                                                   infos: 2, errors: 3)],
         | 
| 40 | 
            -
                      start_at: (Time.now.utc.to_f * 1000).to_i,
         | 
| 41 | 
            -
                      end_at: (Time.now.utc.to_f * 1000).to_i,
         | 
| 42 | 
            -
                      instance_hash: client.instance_hash,
         | 
| 43 | 
            -
                      namespace: 'this.is.a.namespace'
         | 
| 44 | 
            -
                    )
         | 
| 45 | 
            -
                  ]]
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
              end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
              private
         | 
| 50 | 
            -
             | 
| 51 | 
            -
              def new_client(overrides = {})
         | 
| 52 | 
            -
                super(**{
         | 
| 53 | 
            -
                  prefab_datasources: Prefab::Options::DATASOURCES::ALL,
         | 
| 54 | 
            -
                  api_key: '123-development-yourapikey-SDK',
         | 
| 55 | 
            -
                  collect_sync_interval: 1000 # we'll trigger sync manually in our test
         | 
| 56 | 
            -
                }.merge(overrides))
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
            end
         |