sdk-reforge 1.11.2 → 1.12.0
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/.DS_Store +0 -0
 - data/.github/workflows/ruby.yml +1 -1
 - data/CHANGELOG.md +9 -0
 - data/Gemfile +1 -2
 - data/Gemfile.lock +3 -3
 - data/README.md +100 -0
 - data/VERSION +1 -1
 - data/lib/prefab_pb.rb +1 -1
 - data/lib/reforge/client.rb +4 -0
 - data/lib/reforge/internal_logger.rb +149 -19
 - data/lib/reforge/log_level.rb +47 -0
 - data/lib/reforge/log_level_client.rb +169 -0
 - data/lib/reforge/options.rb +4 -1
 - data/lib/reforge/reforge.rb +9 -0
 - data/lib/sdk-reforge.rb +8 -1
 - data/sdk-reforge.gemspec +7 -4
 - data/test/support/common_helpers.rb +5 -2
 - data/test/test_log_level_client.rb +264 -0
 - metadata +6 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 8bd7701858dfa6e149ecf77c03e6912f57a74986e013b2b9557da7c90e39f9b2
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 7962dbe8f2e4e6e5d3042b46e0881365d707803ae7ff1e1a328dd412f2872841
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: eff80aba938418cc6108053256ccaee55fc4f7d5a4c5c8d56178e3dd818ecbfb88e7f1144df65e9d28f6b8de08b640ef83997e11f05f091ac0bedaf01277bacd
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: dbc13318df9207918cf6bc7343bcac5221532a65dd6ee58fbfd61e014a4ba98fcd1f6f6efa2050cb7bcc0823573cdb24bbd541d9d45df8c5e614bf3aa8ba3fc5
         
     | 
    
        data/.DS_Store
    ADDED
    
    | 
         Binary file 
     | 
    
        data/.github/workflows/ruby.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Changelog
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 1.12.0 - 2025-10-31
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - Restore log level functionality with LOG_LEVEL_V2 support
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Make SemanticLogger optional - SDK now works with or without it
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Add stdlib Logger support as alternative to SemanticLogger
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Add InternalLogger that automatically uses SemanticLogger or stdlib Logger
         
     | 
| 
      
 9 
     | 
    
         
            +
            - Add `logger_key` initialization option for configuring dynamic log levels
         
     | 
| 
      
 10 
     | 
    
         
            +
            - Add `stdlib_formatter` method for stdlib Logger integration
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       3 
12 
     | 
    
         
             
            ## 1.11.2 - 2025-10-07
         
     | 
| 
       4 
13 
     | 
    
         | 
| 
       5 
14 
     | 
    
         
             
            - Address OpenSSL issue with vulnerability to truncation attack
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -9,8 +9,6 @@ gem 'uuid' 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            gem 'activesupport', '>= 4'
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            gem 'semantic_logger', '!= 4.16.0', require: "semantic_logger/sync"
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
12 
     | 
    
         
             
            group :development do
         
     | 
| 
       15 
13 
     | 
    
         
             
              gem 'allocation_stats'
         
     | 
| 
       16 
14 
     | 
    
         
             
              gem 'benchmark-ips'
         
     | 
| 
         @@ -21,6 +19,7 @@ group :development do 
     | 
|
| 
       21 
19 
     | 
    
         
             
            end
         
     | 
| 
       22 
20 
     | 
    
         | 
| 
       23 
21 
     | 
    
         
             
            group :test do
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem 'semantic_logger', '!= 4.16.0', require: "semantic_logger/sync"
         
     | 
| 
       24 
23 
     | 
    
         
             
              gem 'minitest'
         
     | 
| 
       25 
24 
     | 
    
         
             
              gem 'minitest-focus'
         
     | 
| 
       26 
25 
     | 
    
         
             
              gem 'minitest-reporters'
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    | 
         @@ -102,7 +102,7 @@ GEM 
     | 
|
| 
       102 
102 
     | 
    
         
             
                  rake (~> 13.0)
         
     | 
| 
       103 
103 
     | 
    
         
             
                macaddr (1.7.2)
         
     | 
| 
       104 
104 
     | 
    
         
             
                  systemu (~> 2.6.5)
         
     | 
| 
       105 
     | 
    
         
            -
                mini_portile2 (2.8. 
     | 
| 
      
 105 
     | 
    
         
            +
                mini_portile2 (2.8.9)
         
     | 
| 
       106 
106 
     | 
    
         
             
                minitest (5.22.3)
         
     | 
| 
       107 
107 
     | 
    
         
             
                minitest-focus (1.4.0)
         
     | 
| 
       108 
108 
     | 
    
         
             
                  minitest (>= 4, < 6)
         
     | 
| 
         @@ -115,7 +115,7 @@ GEM 
     | 
|
| 
       115 
115 
     | 
    
         
             
                multi_xml (0.6.0)
         
     | 
| 
       116 
116 
     | 
    
         
             
                multipart-post (2.4.0)
         
     | 
| 
       117 
117 
     | 
    
         
             
                mutex_m (0.2.0)
         
     | 
| 
       118 
     | 
    
         
            -
                nokogiri (1. 
     | 
| 
      
 118 
     | 
    
         
            +
                nokogiri (1.18.9)
         
     | 
| 
       119 
119 
     | 
    
         
             
                  mini_portile2 (~> 2.8.2)
         
     | 
| 
       120 
120 
     | 
    
         
             
                  racc (~> 1.4)
         
     | 
| 
       121 
121 
     | 
    
         
             
                oauth2 (1.4.11)
         
     | 
| 
         @@ -128,7 +128,7 @@ GEM 
     | 
|
| 
       128 
128 
     | 
    
         
             
                  stringio
         
     | 
| 
       129 
129 
     | 
    
         
             
                public_suffix (5.0.4)
         
     | 
| 
       130 
130 
     | 
    
         
             
                racc (1.8.1)
         
     | 
| 
       131 
     | 
    
         
            -
                rack (3. 
     | 
| 
      
 131 
     | 
    
         
            +
                rack (3.1.18)
         
     | 
| 
       132 
132 
     | 
    
         
             
                rake (13.1.0)
         
     | 
| 
       133 
133 
     | 
    
         
             
                rchardet (1.8.0)
         
     | 
| 
       134 
134 
     | 
    
         
             
                rdoc (6.6.3.1)
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -64,7 +64,107 @@ after_fork do |server, worker| 
     | 
|
| 
       64 
64 
     | 
    
         
             
            end
         
     | 
| 
       65 
65 
     | 
    
         
             
            ```
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
            ## Dynamic Log Levels
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
      
 69 
     | 
    
         
            +
            Reforge supports dynamic log level management for Ruby logging frameworks. This allows you to change log levels in real-time without redeploying your application.
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            Supported loggers:
         
     | 
| 
      
 72 
     | 
    
         
            +
            - SemanticLogger (optional dependency)
         
     | 
| 
      
 73 
     | 
    
         
            +
            - Ruby stdlib Logger
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            ### Setup with SemanticLogger
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            Add semantic_logger to your Gemfile:
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 80 
     | 
    
         
            +
            # Gemfile
         
     | 
| 
      
 81 
     | 
    
         
            +
            gem "semantic_logger"
         
     | 
| 
      
 82 
     | 
    
         
            +
            ```
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            ### Plain Ruby
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 87 
     | 
    
         
            +
            require "semantic_logger"
         
     | 
| 
      
 88 
     | 
    
         
            +
            require "sdk-reforge"
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            client = Reforge::Client.new(
         
     | 
| 
      
 91 
     | 
    
         
            +
              sdk_key: ENV['REFORGE_BACKEND_SDK_KEY'],
         
     | 
| 
      
 92 
     | 
    
         
            +
              logger_key: 'log-levels.default' # optional, this is the default
         
     | 
| 
      
 93 
     | 
    
         
            +
            )
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            SemanticLogger.sync!
         
     | 
| 
      
 96 
     | 
    
         
            +
            SemanticLogger.default_level = :trace # Reforge will handle filtering
         
     | 
| 
      
 97 
     | 
    
         
            +
            SemanticLogger.add_appender(
         
     | 
| 
      
 98 
     | 
    
         
            +
              io: $stdout,
         
     | 
| 
      
 99 
     | 
    
         
            +
              formatter: :json,
         
     | 
| 
      
 100 
     | 
    
         
            +
              filter: client.log_level_client.method(:semantic_filter)
         
     | 
| 
      
 101 
     | 
    
         
            +
            )
         
     | 
| 
      
 102 
     | 
    
         
            +
            ```
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            ### With Rails
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 107 
     | 
    
         
            +
            # Gemfile
         
     | 
| 
      
 108 
     | 
    
         
            +
            gem "amazing_print"
         
     | 
| 
      
 109 
     | 
    
         
            +
            gem "rails_semantic_logger"
         
     | 
| 
      
 110 
     | 
    
         
            +
            ```
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 113 
     | 
    
         
            +
            # config/application.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            $reforge_client = Reforge::Client.new # reads REFORGE_BACKEND_SDK_KEY env var
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            # config/initializers/logging.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            SemanticLogger.sync!
         
     | 
| 
      
 118 
     | 
    
         
            +
            SemanticLogger.default_level = :trace # Reforge will handle filtering
         
     | 
| 
      
 119 
     | 
    
         
            +
            SemanticLogger.add_appender(
         
     | 
| 
      
 120 
     | 
    
         
            +
              io: $stdout,
         
     | 
| 
      
 121 
     | 
    
         
            +
              formatter: Rails.env.development? ? :color : :json,
         
     | 
| 
      
 122 
     | 
    
         
            +
              filter: $reforge_client.log_level_client.method(:semantic_filter)
         
     | 
| 
      
 123 
     | 
    
         
            +
            )
         
     | 
| 
      
 124 
     | 
    
         
            +
            ```
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 127 
     | 
    
         
            +
            # puma.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            on_worker_boot do
         
     | 
| 
      
 129 
     | 
    
         
            +
              SemanticLogger.reopen
         
     | 
| 
      
 130 
     | 
    
         
            +
              Reforge.fork
         
     | 
| 
      
 131 
     | 
    
         
            +
            end
         
     | 
| 
      
 132 
     | 
    
         
            +
            ```
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            ### With Ruby stdlib Logger
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            If you're using Ruby's standard library Logger, you can use a dynamic formatter:
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 139 
     | 
    
         
            +
            require "logger"
         
     | 
| 
      
 140 
     | 
    
         
            +
            require "sdk-reforge"
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            client = Reforge::Client.new(
         
     | 
| 
      
 143 
     | 
    
         
            +
              sdk_key: ENV['REFORGE_BACKEND_SDK_KEY'],
         
     | 
| 
      
 144 
     | 
    
         
            +
              logger_key: 'log-levels.default' # optional, this is the default
         
     | 
| 
      
 145 
     | 
    
         
            +
            )
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            logger = Logger.new($stdout)
         
     | 
| 
      
 148 
     | 
    
         
            +
            logger.level = Logger::DEBUG # Set to most verbose level, Reforge will handle filtering
         
     | 
| 
      
 149 
     | 
    
         
            +
            logger.formatter = client.log_level_client.stdlib_formatter('MyApp')
         
     | 
| 
      
 150 
     | 
    
         
            +
            ```
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            The formatter will check dynamic log levels from Reforge and only output logs that meet the configured threshold.
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            ### Configuration
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
            In Reforge Launch, create a `LOG_LEVEL_V2` config with your desired key (default: `log-levels.default`). The config will be evaluated with the following context:
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 159 
     | 
    
         
            +
            {
         
     | 
| 
      
 160 
     | 
    
         
            +
              "reforge-sdk-logging" => {
         
     | 
| 
      
 161 
     | 
    
         
            +
                "lang" => "ruby",
         
     | 
| 
      
 162 
     | 
    
         
            +
                "logger-path" => "your_app.your_class" # class name converted to lowercase with dots
         
     | 
| 
      
 163 
     | 
    
         
            +
              }
         
     | 
| 
      
 164 
     | 
    
         
            +
            }
         
     | 
| 
      
 165 
     | 
    
         
            +
            ```
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            You can set different log levels for different classes/modules using criteria on the `reforge-sdk-logging.logger-path` property.
         
     | 
| 
       68 
168 
     | 
    
         | 
| 
       69 
169 
     | 
    
         
             
            ## Contributing to reforge sdk for ruby
         
     | 
| 
       70 
170 
     | 
    
         | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.12.0
         
     | 
    
        data/lib/prefab_pb.rb
    CHANGED
    
    | 
         @@ -5,7 +5,7 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require 'google/protobuf'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            descriptor_data = "\n\x0cprefab.proto\x12\x06prefab\"W\n\x14\x43onfigServicePointer\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x13\n\x0bstart_at_id\x18\x02 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x03 \x01(\x03\"\xf7\x04\n\x0b\x43onfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x62ytes\x18\x03 \x01(\x0cH\x00\x12\x10\n\x06\x64ouble\x18\x04 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x05 \x01(\x08H\x00\x12\x31\n\x0fweighted_values\x18\x06 \x01(\x0b\x32\x16.prefab.WeightedValuesH\x00\x12\x33\n\x10limit_definition\x18\x07 \x01(\x0b\x32\x17.prefab.LimitDefinitionH\x00\x12%\n\tlog_level\x18\t \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\n \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x0b \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x12$\n\x08provided\x18\x0c \x01(\x0b\x32\x10.prefab.ProvidedH\x00\x12\'\n\x08\x64uration\x18\x0f \x01(\x0b\x32\x13.prefab.IsoDurationH\x00\x12\x1c\n\x04json\x18\x10 \x01(\x0b\x32\x0c.prefab.JsonH\x00\x12 \n\x06schema\x18\x11 \x01(\x0b\x32\x0e.prefab.SchemaH\x00\x12\x19\n\x0c\x63onfidential\x18\r \x01(\x08H\x01\x88\x01\x01\x12\x19\n\x0c\x64\x65\x63rypt_with\x18\x0e \x01(\tH\x02\x88\x01\x01\x12\x11\n\x04name\x18\x12 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x13 \x01(\tH\x04\x88\x01\x01\x42\x06\n\x04typeB\x0f\n\r_confidentialB\x0f\n\r_decrypt_withB\x07\n\x05_nameB\x0e\n\x0c_description\"\x14\n\x04Json\x12\x0c\n\x04json\x18\x01 \x01(\t\"!\n\x0bIsoDuration\x12\x12\n\ndefinition\x18\x01 \x01(\t\"b\n\x08Provided\x12+\n\x06source\x18\x01 \x01(\x0e\x32\x16.prefab.ProvidedSourceH\x00\x88\x01\x01\x12\x13\n\x06lookup\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_sourceB\t\n\x07_lookup\"B\n\x08IntRange\x12\x12\n\x05start\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x03H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"\x1c\n\nStringList\x12\x0e\n\x06values\x18\x01 \x03(\t\"C\n\rWeightedValue\x12\x0e\n\x06weight\x18\x01 \x01(\x05\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"~\n\x0eWeightedValues\x12.\n\x0fweighted_values\x18\x01 \x03(\x0b\x32\x15.prefab.WeightedValue\x12\"\n\x15hash_by_property_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x18\n\x16_hash_by_property_name\"X\n\x0e\x41piKeyMetadata\x12\x13\n\x06key_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07user_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_key_idB\n\n\x08_user_idJ\x04\x08\x02\x10\x03\"\xa0\x02\n\x07\x43onfigs\x12\x1f\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x0e.prefab.Config\x12<\n\x16\x63onfig_service_pointer\x18\x02 \x01(\x0b\x32\x1c.prefab.ConfigServicePointer\x12\x34\n\x0f\x61pikey_metadata\x18\x03 \x01(\x0b\x32\x16.prefab.ApiKeyMetadataH\x00\x88\x01\x01\x12\x30\n\x0f\x64\x65\x66\x61ult_context\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSetH\x01\x88\x01\x01\x12\x17\n\nkeep_alive\x18\x05 \x01(\x08H\x02\x88\x01\x01\x42\x12\n\x10_apikey_metadataB\x12\n\x10_default_contextB\r\n\x0b_keep_alive\"\xa4\x04\n\x06\x43onfig\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x12\n\nproject_id\x18\x02 \x01(\x03\x12\x0b\n\x03key\x18\x03 \x01(\t\x12%\n\nchanged_by\x18\x04 \x01(\x0b\x32\x11.prefab.ChangedBy\x12\x1f\n\x04rows\x18\x05 \x03(\x0b\x32\x11.prefab.ConfigRow\x12-\n\x10\x61llowable_values\x18\x06 \x03(\x0b\x32\x13.prefab.ConfigValue\x12\'\n\x0b\x63onfig_type\x18\x07 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x15\n\x08\x64raft_id\x18\x08 \x01(\x03H\x00\x88\x01\x01\x12,\n\nvalue_type\x18\t \x01(\x0e\x32\x18.prefab.Config.ValueType\x12\x1a\n\x12send_to_client_sdk\x18\n \x01(\x08\x12\x17\n\nschema_key\x18\x0b \x01(\tH\x01\x88\x01\x01\"\xb6\x01\n\tValueType\x12\x16\n\x12NOT_SET_VALUE_TYPE\x10\x00\x12\x07\n\x03INT\x10\x01\x12\n\n\x06STRING\x10\x02\x12\t\n\x05\x42YTES\x10\x03\x12\n\n\x06\x44OUBLE\x10\x04\x12\x08\n\x04\x42OOL\x10\x05\x12\x14\n\x10LIMIT_DEFINITION\x10\x07\x12\r\n\tLOG_LEVEL\x10\t\x12\x0f\n\x0bSTRING_LIST\x10\n\x12\r\n\tINT_RANGE\x10\x0b\x12\x0c\n\x08\x44URATION\x10\x0c\x12\x08\n\x04JSON\x10\rB\x0b\n\t_draft_idB\r\n\x0b_schema_key\"V\n\tChangedBy\x12\x0f\n\x07user_id\x18\x01 \x01(\x03\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x12\n\napi_key_id\x18\x03 \x01(\t\x12\x15\n\ruser_identity\x18\x04 \x01(\t\"\xe4\x01\n\tConfigRow\x12\x1b\n\x0eproject_env_id\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12(\n\x06values\x18\x02 \x03(\x0b\x32\x18.prefab.ConditionalValue\x12\x35\n\nproperties\x18\x03 \x03(\x0b\x32!.prefab.ConfigRow.PropertiesEntry\x1a\x46\n\x0fPropertiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x11\n\x0f_project_env_id\"[\n\x10\x43onditionalValue\x12#\n\x08\x63riteria\x18\x01 \x03(\x0b\x32\x11.prefab.Criterion\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x96\x06\n\tCriterion\x12\x15\n\rproperty_name\x18\x01 \x01(\t\x12\x35\n\x08operator\x18\x02 \x01(\x0e\x32#.prefab.Criterion.CriterionOperator\x12+\n\x0evalue_to_match\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x8d\x05\n\x11\x43riterionOperator\x12\x0b\n\x07NOT_SET\x10\x00\x12\x11\n\rLOOKUP_KEY_IN\x10\x01\x12\x15\n\x11LOOKUP_KEY_NOT_IN\x10\x02\x12\n\n\x06IN_SEG\x10\x03\x12\x0e\n\nNOT_IN_SEG\x10\x04\x12\x0f\n\x0b\x41LWAYS_TRUE\x10\x05\x12\x12\n\x0ePROP_IS_ONE_OF\x10\x06\x12\x16\n\x12PROP_IS_NOT_ONE_OF\x10\x07\x12\x19\n\x15PROP_ENDS_WITH_ONE_OF\x10\x08\x12!\n\x1dPROP_DOES_NOT_END_WITH_ONE_OF\x10\t\x12\x16\n\x12HIERARCHICAL_MATCH\x10\n\x12\x10\n\x0cIN_INT_RANGE\x10\x0b\x12\x1b\n\x17PROP_STARTS_WITH_ONE_OF\x10\x0c\x12#\n\x1fPROP_DOES_NOT_START_WITH_ONE_OF\x10\r\x12\x18\n\x14PROP_CONTAINS_ONE_OF\x10\x0e\x12 \n\x1cPROP_DOES_NOT_CONTAIN_ONE_OF\x10\x0f\x12\x12\n\x0ePROP_LESS_THAN\x10\x10\x12\x1b\n\x17PROP_LESS_THAN_OR_EQUAL\x10\x11\x12\x15\n\x11PROP_GREATER_THAN\x10\x12\x12\x1e\n\x1aPROP_GREATER_THAN_OR_EQUAL\x10\x13\x12\x0f\n\x0bPROP_BEFORE\x10\x14\x12\x0e\n\nPROP_AFTER\x10\x15\x12\x10\n\x0cPROP_MATCHES\x10\x16\x12\x17\n\x13PROP_DOES_NOT_MATCH\x10\x17\x12\x19\n\x15PROP_SEMVER_LESS_THAN\x10\x18\x12\x15\n\x11PROP_SEMVER_EQUAL\x10\x19\x12\x1c\n\x18PROP_SEMVER_GREATER_THAN\x10\x1a\"\x89\x01\n\x07Loggers\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\x12\x15\n\rinstance_hash\x18\x04 \x01(\t\x12\x16\n\tnamespace\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\xd9\x01\n\x06Logger\x12\x13\n\x0blogger_name\x18\x01 \x01(\t\x12\x13\n\x06traces\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06\x64\x65\x62ugs\x18\x03 \x01(\x03H\x01\x88\x01\x01\x12\x12\n\x05infos\x18\x04 \x01(\x03H\x02\x88\x01\x01\x12\x12\n\x05warns\x18\x05 \x01(\x03H\x03\x88\x01\x01\x12\x13\n\x06\x65rrors\x18\x06 \x01(\x03H\x04\x88\x01\x01\x12\x13\n\x06\x66\x61tals\x18\x07 \x01(\x03H\x05\x88\x01\x01\x42\t\n\x07_tracesB\t\n\x07_debugsB\x08\n\x06_infosB\x08\n\x06_warnsB\t\n\x07_errorsB\t\n\x07_fatals\"\x16\n\x14LoggerReportResponse\"\xdb\x03\n\rLimitResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\x12\x16\n\x0e\x65nforced_group\x18\x03 \x01(\t\x12\x16\n\x0e\x63urrent_bucket\x18\x04 \x01(\x03\x12\x14\n\x0cpolicy_group\x18\x05 \x01(\t\x12;\n\x0bpolicy_name\x18\x06 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\x14\n\x0cpolicy_limit\x18\x07 \x01(\x05\x12\x0e\n\x06\x61mount\x18\x08 \x01(\x03\x12\x16\n\x0elimit_reset_at\x18\t \x01(\x03\x12\x39\n\x0csafety_level\x18\n \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"\xa9\x01\n\x10LimitPolicyNames\x12\x0b\n\x07NOT_SET\x10\x00\x12\x14\n\x10SECONDLY_ROLLING\x10\x01\x12\x14\n\x10MINUTELY_ROLLING\x10\x03\x12\x12\n\x0eHOURLY_ROLLING\x10\x05\x12\x11\n\rDAILY_ROLLING\x10\x07\x12\x13\n\x0fMONTHLY_ROLLING\x10\x08\x12\x0c\n\x08INFINITE\x10\t\x12\x12\n\x0eYEARLY_ROLLING\x10\n\"\x99\x02\n\x0cLimitRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x16\n\x0e\x61\x63quire_amount\x18\x02 \x01(\x05\x12\x0e\n\x06groups\x18\x03 \x03(\t\x12:\n\x0elimit_combiner\x18\x04 \x01(\x0e\x32\".prefab.LimitRequest.LimitCombiner\x12\x1e\n\x16\x61llow_partial_response\x18\x05 \x01(\x08\x12\x39\n\x0csafety_level\x18\x06 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"6\n\rLimitCombiner\x12\x0b\n\x07NOT_SET\x10\x00\x12\x0b\n\x07MINIMUM\x10\x01\x12\x0b\n\x07MAXIMUM\x10\x02\"/\n\nContextSet\x12!\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x0f.prefab.Context\"\x96\x01\n\x07\x43ontext\x12\x11\n\x04type\x18\x01 \x01(\tH\x00\x88\x01\x01\x12+\n\x06values\x18\x02 \x03(\x0b\x32\x1b.prefab.Context.ValuesEntry\x1a\x42\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x07\n\x05_type\"\x93\x01\n\x08Identity\x12\x13\n\x06lookup\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x34\n\nattributes\x18\x02 \x03(\x0b\x32 .prefab.Identity.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_lookup\"\xd6\x02\n\x18\x43onfigEvaluationMetaData\x12\x1d\n\x10\x63onfig_row_index\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12$\n\x17\x63onditional_value_index\x18\x02 \x01(\x03H\x01\x88\x01\x01\x12!\n\x14weighted_value_index\x18\x03 \x01(\x03H\x02\x88\x01\x01\x12%\n\x04type\x18\x04 \x01(\x0e\x32\x12.prefab.ConfigTypeH\x03\x88\x01\x01\x12\x0f\n\x02id\x18\x05 \x01(\x03H\x04\x88\x01\x01\x12\x31\n\nvalue_type\x18\x06 \x01(\x0e\x32\x18.prefab.Config.ValueTypeH\x05\x88\x01\x01\x42\x13\n\x11_config_row_indexB\x1a\n\x18_conditional_value_indexB\x17\n\x15_weighted_value_indexB\x07\n\x05_typeB\x05\n\x03_idB\r\n\x0b_value_type\"\x8b\x03\n\x11\x43lientConfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x10\n\x06\x64ouble\x18\x03 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x04 \x01(\x08H\x00\x12%\n\tlog_level\x18\x05 \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\x07 \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x08 \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x12*\n\x08\x64uration\x18\t \x01(\x0b\x32\x16.prefab.ClientDurationH\x00\x12\x1c\n\x04json\x18\n \x01(\x0b\x32\x0c.prefab.JsonH\x00\x12I\n\x1a\x63onfig_evaluation_metadata\x18\x06 \x01(\x0b\x32 .prefab.ConfigEvaluationMetaDataH\x01\x88\x01\x01\x42\x06\n\x04typeB\x1d\n\x1b_config_evaluation_metadata\"D\n\x0e\x43lientDuration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x12\x12\n\ndefinition\x18\x03 \x01(\t\"\xa4\x02\n\x11\x43onfigEvaluations\x12\x35\n\x06values\x18\x01 \x03(\x0b\x32%.prefab.ConfigEvaluations.ValuesEntry\x12\x34\n\x0f\x61pikey_metadata\x18\x02 \x01(\x0b\x32\x16.prefab.ApiKeyMetadataH\x00\x88\x01\x01\x12\x30\n\x0f\x64\x65\x66\x61ult_context\x18\x03 \x01(\x0b\x32\x12.prefab.ContextSetH\x01\x88\x01\x01\x1aH\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.prefab.ClientConfigValue:\x02\x38\x01\x42\x12\n\x10_apikey_metadataB\x12\n\x10_default_context\"\xa8\x02\n\x0fLimitDefinition\x12;\n\x0bpolicy_name\x18\x02 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\r\n\x05limit\x18\x03 \x01(\x05\x12\r\n\x05\x62urst\x18\x04 \x01(\x05\x12\x12\n\naccount_id\x18\x05 \x01(\x03\x12\x15\n\rlast_modified\x18\x06 \x01(\x03\x12\x12\n\nreturnable\x18\x07 \x01(\x08\x12\x39\n\x0csafety_level\x18\x08 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"@\n\x0bSafetyLevel\x12\x0b\n\x07NOT_SET\x10\x00\x12\x12\n\x0eL4_BEST_EFFORT\x10\x04\x12\x10\n\x0cL5_BOMBPROOF\x10\x05\"@\n\x10LimitDefinitions\x12,\n\x0b\x64\x65\x66initions\x18\x01 \x03(\x0b\x32\x17.prefab.LimitDefinition\"\x8a\x01\n\x0f\x42ufferedRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x14\n\x0c\x63ontent_type\x18\x06 \x01(\t\x12\x0c\n\x04\x66ifo\x18\x07 \x01(\x08\"\x94\x01\n\x0c\x42\x61tchRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x16\n\x0e\x62\x61tch_template\x18\x06 \x01(\t\x12\x17\n\x0f\x62\x61tch_separator\x18\x07 \x01(\t\" \n\rBasicResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\"3\n\x10\x43reationResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0e\n\x06new_id\x18\x02 \x01(\x03\"h\n\x07IdBlock\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\r\n\x05start\x18\x04 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x03\"a\n\x0eIdBlockRequest\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x03\"\x8a\x01\n\x0c\x43ontextShape\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x39\n\x0b\x66ield_types\x18\x02 \x03(\x0b\x32$.prefab.ContextShape.FieldTypesEntry\x1a\x31\n\x0f\x46ieldTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"[\n\rContextShapes\x12$\n\x06shapes\x18\x01 \x03(\x0b\x32\x14.prefab.ContextShape\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"C\n\rEvaluatedKeys\x12\x0c\n\x04keys\x18\x01 \x03(\t\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\x93\x01\n\x0f\x45valuatedConfig\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x0e\x63onfig_version\x18\x02 \x01(\x03\x12#\n\x06result\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\x12#\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSet\x12\x11\n\ttimestamp\x18\x05 \x01(\x03\"<\n\x10\x45valuatedConfigs\x12(\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x17.prefab.EvaluatedConfig\"\xc4\x03\n\x17\x43onfigEvaluationCounter\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x16\n\tconfig_id\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x1b\n\x0eselected_index\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x30\n\x0eselected_value\x18\x04 \x01(\x0b\x32\x13.prefab.ConfigValueH\x02\x88\x01\x01\x12\x1d\n\x10\x63onfig_row_index\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17\x63onditional_value_index\x18\x06 \x01(\rH\x04\x88\x01\x01\x12!\n\x14weighted_value_index\x18\x07 \x01(\rH\x05\x88\x01\x01\x12\x36\n\x06reason\x18\x08 \x01(\x0e\x32&.prefab.ConfigEvaluationCounter.Reason\"\x15\n\x06Reason\x12\x0b\n\x07UNKNOWN\x10\x00\x42\x0c\n\n_config_idB\x11\n\x0f_selected_indexB\x11\n\x0f_selected_valueB\x13\n\x11_config_row_indexB\x1a\n\x18_conditional_value_indexB\x17\n\x15_weighted_value_index\"{\n\x17\x43onfigEvaluationSummary\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x04type\x18\x02 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x31\n\x08\x63ounters\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationCounter\"k\n\x19\x43onfigEvaluationSummaries\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x32\n\tsummaries\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationSummary\"Z\n\x15LoggersTelemetryEvent\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\"\x98\x02\n\x0eTelemetryEvent\x12\x36\n\tsummaries\x18\x02 \x01(\x0b\x32!.prefab.ConfigEvaluationSummariesH\x00\x12\x33\n\x10\x65xample_contexts\x18\x03 \x01(\x0b\x32\x17.prefab.ExampleContextsH\x00\x12+\n\x0c\x63lient_stats\x18\x04 \x01(\x0b\x32\x13.prefab.ClientStatsH\x00\x12\x30\n\x07loggers\x18\x05 \x01(\x0b\x32\x1d.prefab.LoggersTelemetryEventH\x00\x12/\n\x0e\x63ontext_shapes\x18\x06 \x01(\x0b\x32\x15.prefab.ContextShapesH\x00\x42\t\n\x07payload\"P\n\x0fTelemetryEvents\x12\x15\n\rinstance_hash\x18\x01 \x01(\t\x12&\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x16.prefab.TelemetryEvent\"*\n\x17TelemetryEventsResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\";\n\x0f\x45xampleContexts\x12(\n\x08\x65xamples\x18\x01 \x03(\x0b\x32\x16.prefab.ExampleContext\"K\n\x0e\x45xampleContext\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12&\n\ncontextSet\x18\x02 \x01(\x0b\x32\x12.prefab.ContextSet\"F\n\x0b\x43lientStats\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x1b\n\x13\x64ropped_event_count\x18\x03 \x01(\x04\"}\n\x06Schema\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12.\n\x0bschema_type\x18\x02 \x01(\x0e\x32\x19.prefab.Schema.SchemaType\"3\n\nSchemaType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03ZOD\x10\x01\x12\x0f\n\x0bJSON_SCHEMA\x10\x02*:\n\x0eProvidedSource\x12\x1b\n\x17PROVIDED_SOURCE_NOT_SET\x10\x00\x12\x0b\n\x07\x45NV_VAR\x10\x01*\x8e\x01\n\nConfigType\x12\x17\n\x13NOT_SET_CONFIG_TYPE\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\x10\n\x0c\x46\x45\x41TURE_FLAG\x10\x02\x12\r\n\tLOG_LEVEL\x10\x03\x12\x0b\n\x07SEGMENT\x10\x04\x12\x14\n\x10LIMIT_DEFINITION\x10\x05\x12\x0b\n\x07\x44\x45LETED\x10\x06\x12\n\n\x06SCHEMA\x10\x07*a\n\x08LogLevel\x12\x15\n\x11NOT_SET_LOG_LEVEL\x10\x00\x12\t\n\x05TRACE\x10\x01\x12\t\n\x05\x44\x45\x42UG\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x08\n\x04WARN\x10\x05\x12\t\n\x05\x45RROR\x10\x06\x12\t\n\x05\x46\x41TAL\x10\t*G\n\tOnFailure\x12\x0b\n\x07NOT_SET\x10\x00\x12\x10\n\x0cLOG_AND_PASS\x10\x01\x12\x10\n\x0cLOG_AND_FAIL\x10\x02\x12\t\n\x05THROW\x10\x03\x42L\n\x13\x63loud.prefab.domainB\x06PrefabZ-github.com/prefab-cloud/prefab-cloud-go/protob\x06proto3"
         
     | 
| 
      
 8 
     | 
    
         
            +
            descriptor_data = "\n\x0cprefab.proto\x12\x06prefab\"W\n\x14\x43onfigServicePointer\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x13\n\x0bstart_at_id\x18\x02 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x03 \x01(\x03\"\xf7\x04\n\x0b\x43onfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x62ytes\x18\x03 \x01(\x0cH\x00\x12\x10\n\x06\x64ouble\x18\x04 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x05 \x01(\x08H\x00\x12\x31\n\x0fweighted_values\x18\x06 \x01(\x0b\x32\x16.prefab.WeightedValuesH\x00\x12\x33\n\x10limit_definition\x18\x07 \x01(\x0b\x32\x17.prefab.LimitDefinitionH\x00\x12%\n\tlog_level\x18\t \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\n \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x0b \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x12$\n\x08provided\x18\x0c \x01(\x0b\x32\x10.prefab.ProvidedH\x00\x12\'\n\x08\x64uration\x18\x0f \x01(\x0b\x32\x13.prefab.IsoDurationH\x00\x12\x1c\n\x04json\x18\x10 \x01(\x0b\x32\x0c.prefab.JsonH\x00\x12 \n\x06schema\x18\x11 \x01(\x0b\x32\x0e.prefab.SchemaH\x00\x12\x19\n\x0c\x63onfidential\x18\r \x01(\x08H\x01\x88\x01\x01\x12\x19\n\x0c\x64\x65\x63rypt_with\x18\x0e \x01(\tH\x02\x88\x01\x01\x12\x11\n\x04name\x18\x12 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x13 \x01(\tH\x04\x88\x01\x01\x42\x06\n\x04typeB\x0f\n\r_confidentialB\x0f\n\r_decrypt_withB\x07\n\x05_nameB\x0e\n\x0c_description\"\x14\n\x04Json\x12\x0c\n\x04json\x18\x01 \x01(\t\"!\n\x0bIsoDuration\x12\x12\n\ndefinition\x18\x01 \x01(\t\"b\n\x08Provided\x12+\n\x06source\x18\x01 \x01(\x0e\x32\x16.prefab.ProvidedSourceH\x00\x88\x01\x01\x12\x13\n\x06lookup\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_sourceB\t\n\x07_lookup\"B\n\x08IntRange\x12\x12\n\x05start\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x03H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"\x1c\n\nStringList\x12\x0e\n\x06values\x18\x01 \x03(\t\"C\n\rWeightedValue\x12\x0e\n\x06weight\x18\x01 \x01(\x05\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"~\n\x0eWeightedValues\x12.\n\x0fweighted_values\x18\x01 \x03(\x0b\x32\x15.prefab.WeightedValue\x12\"\n\x15hash_by_property_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x18\n\x16_hash_by_property_name\"X\n\x0e\x41piKeyMetadata\x12\x13\n\x06key_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07user_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_key_idB\n\n\x08_user_idJ\x04\x08\x02\x10\x03\"\xa0\x02\n\x07\x43onfigs\x12\x1f\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x0e.prefab.Config\x12<\n\x16\x63onfig_service_pointer\x18\x02 \x01(\x0b\x32\x1c.prefab.ConfigServicePointer\x12\x34\n\x0f\x61pikey_metadata\x18\x03 \x01(\x0b\x32\x16.prefab.ApiKeyMetadataH\x00\x88\x01\x01\x12\x30\n\x0f\x64\x65\x66\x61ult_context\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSetH\x01\x88\x01\x01\x12\x17\n\nkeep_alive\x18\x05 \x01(\x08H\x02\x88\x01\x01\x42\x12\n\x10_apikey_metadataB\x12\n\x10_default_contextB\r\n\x0b_keep_alive\"\xa4\x04\n\x06\x43onfig\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x12\n\nproject_id\x18\x02 \x01(\x03\x12\x0b\n\x03key\x18\x03 \x01(\t\x12%\n\nchanged_by\x18\x04 \x01(\x0b\x32\x11.prefab.ChangedBy\x12\x1f\n\x04rows\x18\x05 \x03(\x0b\x32\x11.prefab.ConfigRow\x12-\n\x10\x61llowable_values\x18\x06 \x03(\x0b\x32\x13.prefab.ConfigValue\x12\'\n\x0b\x63onfig_type\x18\x07 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x15\n\x08\x64raft_id\x18\x08 \x01(\x03H\x00\x88\x01\x01\x12,\n\nvalue_type\x18\t \x01(\x0e\x32\x18.prefab.Config.ValueType\x12\x1a\n\x12send_to_client_sdk\x18\n \x01(\x08\x12\x17\n\nschema_key\x18\x0b \x01(\tH\x01\x88\x01\x01\"\xb6\x01\n\tValueType\x12\x16\n\x12NOT_SET_VALUE_TYPE\x10\x00\x12\x07\n\x03INT\x10\x01\x12\n\n\x06STRING\x10\x02\x12\t\n\x05\x42YTES\x10\x03\x12\n\n\x06\x44OUBLE\x10\x04\x12\x08\n\x04\x42OOL\x10\x05\x12\x14\n\x10LIMIT_DEFINITION\x10\x07\x12\r\n\tLOG_LEVEL\x10\t\x12\x0f\n\x0bSTRING_LIST\x10\n\x12\r\n\tINT_RANGE\x10\x0b\x12\x0c\n\x08\x44URATION\x10\x0c\x12\x08\n\x04JSON\x10\rB\x0b\n\t_draft_idB\r\n\x0b_schema_key\"V\n\tChangedBy\x12\x0f\n\x07user_id\x18\x01 \x01(\x03\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x12\n\napi_key_id\x18\x03 \x01(\t\x12\x15\n\ruser_identity\x18\x04 \x01(\t\"\xe4\x01\n\tConfigRow\x12\x1b\n\x0eproject_env_id\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12(\n\x06values\x18\x02 \x03(\x0b\x32\x18.prefab.ConditionalValue\x12\x35\n\nproperties\x18\x03 \x03(\x0b\x32!.prefab.ConfigRow.PropertiesEntry\x1a\x46\n\x0fPropertiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x11\n\x0f_project_env_id\"[\n\x10\x43onditionalValue\x12#\n\x08\x63riteria\x18\x01 \x03(\x0b\x32\x11.prefab.Criterion\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x96\x06\n\tCriterion\x12\x15\n\rproperty_name\x18\x01 \x01(\t\x12\x35\n\x08operator\x18\x02 \x01(\x0e\x32#.prefab.Criterion.CriterionOperator\x12+\n\x0evalue_to_match\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x8d\x05\n\x11\x43riterionOperator\x12\x0b\n\x07NOT_SET\x10\x00\x12\x11\n\rLOOKUP_KEY_IN\x10\x01\x12\x15\n\x11LOOKUP_KEY_NOT_IN\x10\x02\x12\n\n\x06IN_SEG\x10\x03\x12\x0e\n\nNOT_IN_SEG\x10\x04\x12\x0f\n\x0b\x41LWAYS_TRUE\x10\x05\x12\x12\n\x0ePROP_IS_ONE_OF\x10\x06\x12\x16\n\x12PROP_IS_NOT_ONE_OF\x10\x07\x12\x19\n\x15PROP_ENDS_WITH_ONE_OF\x10\x08\x12!\n\x1dPROP_DOES_NOT_END_WITH_ONE_OF\x10\t\x12\x16\n\x12HIERARCHICAL_MATCH\x10\n\x12\x10\n\x0cIN_INT_RANGE\x10\x0b\x12\x1b\n\x17PROP_STARTS_WITH_ONE_OF\x10\x0c\x12#\n\x1fPROP_DOES_NOT_START_WITH_ONE_OF\x10\r\x12\x18\n\x14PROP_CONTAINS_ONE_OF\x10\x0e\x12 \n\x1cPROP_DOES_NOT_CONTAIN_ONE_OF\x10\x0f\x12\x12\n\x0ePROP_LESS_THAN\x10\x10\x12\x1b\n\x17PROP_LESS_THAN_OR_EQUAL\x10\x11\x12\x15\n\x11PROP_GREATER_THAN\x10\x12\x12\x1e\n\x1aPROP_GREATER_THAN_OR_EQUAL\x10\x13\x12\x0f\n\x0bPROP_BEFORE\x10\x14\x12\x0e\n\nPROP_AFTER\x10\x15\x12\x10\n\x0cPROP_MATCHES\x10\x16\x12\x17\n\x13PROP_DOES_NOT_MATCH\x10\x17\x12\x19\n\x15PROP_SEMVER_LESS_THAN\x10\x18\x12\x15\n\x11PROP_SEMVER_EQUAL\x10\x19\x12\x1c\n\x18PROP_SEMVER_GREATER_THAN\x10\x1a\"\x89\x01\n\x07Loggers\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\x12\x15\n\rinstance_hash\x18\x04 \x01(\t\x12\x16\n\tnamespace\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\xd9\x01\n\x06Logger\x12\x13\n\x0blogger_name\x18\x01 \x01(\t\x12\x13\n\x06traces\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06\x64\x65\x62ugs\x18\x03 \x01(\x03H\x01\x88\x01\x01\x12\x12\n\x05infos\x18\x04 \x01(\x03H\x02\x88\x01\x01\x12\x12\n\x05warns\x18\x05 \x01(\x03H\x03\x88\x01\x01\x12\x13\n\x06\x65rrors\x18\x06 \x01(\x03H\x04\x88\x01\x01\x12\x13\n\x06\x66\x61tals\x18\x07 \x01(\x03H\x05\x88\x01\x01\x42\t\n\x07_tracesB\t\n\x07_debugsB\x08\n\x06_infosB\x08\n\x06_warnsB\t\n\x07_errorsB\t\n\x07_fatals\"\x16\n\x14LoggerReportResponse\"\xdb\x03\n\rLimitResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\x12\x16\n\x0e\x65nforced_group\x18\x03 \x01(\t\x12\x16\n\x0e\x63urrent_bucket\x18\x04 \x01(\x03\x12\x14\n\x0cpolicy_group\x18\x05 \x01(\t\x12;\n\x0bpolicy_name\x18\x06 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\x14\n\x0cpolicy_limit\x18\x07 \x01(\x05\x12\x0e\n\x06\x61mount\x18\x08 \x01(\x03\x12\x16\n\x0elimit_reset_at\x18\t \x01(\x03\x12\x39\n\x0csafety_level\x18\n \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"\xa9\x01\n\x10LimitPolicyNames\x12\x0b\n\x07NOT_SET\x10\x00\x12\x14\n\x10SECONDLY_ROLLING\x10\x01\x12\x14\n\x10MINUTELY_ROLLING\x10\x03\x12\x12\n\x0eHOURLY_ROLLING\x10\x05\x12\x11\n\rDAILY_ROLLING\x10\x07\x12\x13\n\x0fMONTHLY_ROLLING\x10\x08\x12\x0c\n\x08INFINITE\x10\t\x12\x12\n\x0eYEARLY_ROLLING\x10\n\"\x99\x02\n\x0cLimitRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x16\n\x0e\x61\x63quire_amount\x18\x02 \x01(\x05\x12\x0e\n\x06groups\x18\x03 \x03(\t\x12:\n\x0elimit_combiner\x18\x04 \x01(\x0e\x32\".prefab.LimitRequest.LimitCombiner\x12\x1e\n\x16\x61llow_partial_response\x18\x05 \x01(\x08\x12\x39\n\x0csafety_level\x18\x06 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"6\n\rLimitCombiner\x12\x0b\n\x07NOT_SET\x10\x00\x12\x0b\n\x07MINIMUM\x10\x01\x12\x0b\n\x07MAXIMUM\x10\x02\"/\n\nContextSet\x12!\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x0f.prefab.Context\"\x96\x01\n\x07\x43ontext\x12\x11\n\x04type\x18\x01 \x01(\tH\x00\x88\x01\x01\x12+\n\x06values\x18\x02 \x03(\x0b\x32\x1b.prefab.Context.ValuesEntry\x1a\x42\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x07\n\x05_type\"\x93\x01\n\x08Identity\x12\x13\n\x06lookup\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x34\n\nattributes\x18\x02 \x03(\x0b\x32 .prefab.Identity.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_lookup\"\xd6\x02\n\x18\x43onfigEvaluationMetaData\x12\x1d\n\x10\x63onfig_row_index\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12$\n\x17\x63onditional_value_index\x18\x02 \x01(\x03H\x01\x88\x01\x01\x12!\n\x14weighted_value_index\x18\x03 \x01(\x03H\x02\x88\x01\x01\x12%\n\x04type\x18\x04 \x01(\x0e\x32\x12.prefab.ConfigTypeH\x03\x88\x01\x01\x12\x0f\n\x02id\x18\x05 \x01(\x03H\x04\x88\x01\x01\x12\x31\n\nvalue_type\x18\x06 \x01(\x0e\x32\x18.prefab.Config.ValueTypeH\x05\x88\x01\x01\x42\x13\n\x11_config_row_indexB\x1a\n\x18_conditional_value_indexB\x17\n\x15_weighted_value_indexB\x07\n\x05_typeB\x05\n\x03_idB\r\n\x0b_value_type\"\x8b\x03\n\x11\x43lientConfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x10\n\x06\x64ouble\x18\x03 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x04 \x01(\x08H\x00\x12%\n\tlog_level\x18\x05 \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\x07 \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x08 \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x12*\n\x08\x64uration\x18\t \x01(\x0b\x32\x16.prefab.ClientDurationH\x00\x12\x1c\n\x04json\x18\n \x01(\x0b\x32\x0c.prefab.JsonH\x00\x12I\n\x1a\x63onfig_evaluation_metadata\x18\x06 \x01(\x0b\x32 .prefab.ConfigEvaluationMetaDataH\x01\x88\x01\x01\x42\x06\n\x04typeB\x1d\n\x1b_config_evaluation_metadata\"D\n\x0e\x43lientDuration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x12\x12\n\ndefinition\x18\x03 \x01(\t\"\xa4\x02\n\x11\x43onfigEvaluations\x12\x35\n\x06values\x18\x01 \x03(\x0b\x32%.prefab.ConfigEvaluations.ValuesEntry\x12\x34\n\x0f\x61pikey_metadata\x18\x02 \x01(\x0b\x32\x16.prefab.ApiKeyMetadataH\x00\x88\x01\x01\x12\x30\n\x0f\x64\x65\x66\x61ult_context\x18\x03 \x01(\x0b\x32\x12.prefab.ContextSetH\x01\x88\x01\x01\x1aH\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.prefab.ClientConfigValue:\x02\x38\x01\x42\x12\n\x10_apikey_metadataB\x12\n\x10_default_context\"\xa8\x02\n\x0fLimitDefinition\x12;\n\x0bpolicy_name\x18\x02 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\r\n\x05limit\x18\x03 \x01(\x05\x12\r\n\x05\x62urst\x18\x04 \x01(\x05\x12\x12\n\naccount_id\x18\x05 \x01(\x03\x12\x15\n\rlast_modified\x18\x06 \x01(\x03\x12\x12\n\nreturnable\x18\x07 \x01(\x08\x12\x39\n\x0csafety_level\x18\x08 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"@\n\x0bSafetyLevel\x12\x0b\n\x07NOT_SET\x10\x00\x12\x12\n\x0eL4_BEST_EFFORT\x10\x04\x12\x10\n\x0cL5_BOMBPROOF\x10\x05\"@\n\x10LimitDefinitions\x12,\n\x0b\x64\x65\x66initions\x18\x01 \x03(\x0b\x32\x17.prefab.LimitDefinition\"\x8a\x01\n\x0f\x42ufferedRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x14\n\x0c\x63ontent_type\x18\x06 \x01(\t\x12\x0c\n\x04\x66ifo\x18\x07 \x01(\x08\"\x94\x01\n\x0c\x42\x61tchRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x16\n\x0e\x62\x61tch_template\x18\x06 \x01(\t\x12\x17\n\x0f\x62\x61tch_separator\x18\x07 \x01(\t\" \n\rBasicResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\"3\n\x10\x43reationResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0e\n\x06new_id\x18\x02 \x01(\x03\"h\n\x07IdBlock\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\r\n\x05start\x18\x04 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x03\"a\n\x0eIdBlockRequest\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x03\"\x8a\x01\n\x0c\x43ontextShape\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x39\n\x0b\x66ield_types\x18\x02 \x03(\x0b\x32$.prefab.ContextShape.FieldTypesEntry\x1a\x31\n\x0f\x46ieldTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"[\n\rContextShapes\x12$\n\x06shapes\x18\x01 \x03(\x0b\x32\x14.prefab.ContextShape\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"C\n\rEvaluatedKeys\x12\x0c\n\x04keys\x18\x01 \x03(\t\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\x93\x01\n\x0f\x45valuatedConfig\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x0e\x63onfig_version\x18\x02 \x01(\x03\x12#\n\x06result\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\x12#\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSet\x12\x11\n\ttimestamp\x18\x05 \x01(\x03\"<\n\x10\x45valuatedConfigs\x12(\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x17.prefab.EvaluatedConfig\"\xc4\x03\n\x17\x43onfigEvaluationCounter\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x16\n\tconfig_id\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x1b\n\x0eselected_index\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x30\n\x0eselected_value\x18\x04 \x01(\x0b\x32\x13.prefab.ConfigValueH\x02\x88\x01\x01\x12\x1d\n\x10\x63onfig_row_index\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17\x63onditional_value_index\x18\x06 \x01(\rH\x04\x88\x01\x01\x12!\n\x14weighted_value_index\x18\x07 \x01(\rH\x05\x88\x01\x01\x12\x36\n\x06reason\x18\x08 \x01(\x0e\x32&.prefab.ConfigEvaluationCounter.Reason\"\x15\n\x06Reason\x12\x0b\n\x07UNKNOWN\x10\x00\x42\x0c\n\n_config_idB\x11\n\x0f_selected_indexB\x11\n\x0f_selected_valueB\x13\n\x11_config_row_indexB\x1a\n\x18_conditional_value_indexB\x17\n\x15_weighted_value_index\"{\n\x17\x43onfigEvaluationSummary\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x04type\x18\x02 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x31\n\x08\x63ounters\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationCounter\"k\n\x19\x43onfigEvaluationSummaries\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x32\n\tsummaries\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationSummary\"Z\n\x15LoggersTelemetryEvent\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\"\x98\x02\n\x0eTelemetryEvent\x12\x36\n\tsummaries\x18\x02 \x01(\x0b\x32!.prefab.ConfigEvaluationSummariesH\x00\x12\x33\n\x10\x65xample_contexts\x18\x03 \x01(\x0b\x32\x17.prefab.ExampleContextsH\x00\x12+\n\x0c\x63lient_stats\x18\x04 \x01(\x0b\x32\x13.prefab.ClientStatsH\x00\x12\x30\n\x07loggers\x18\x05 \x01(\x0b\x32\x1d.prefab.LoggersTelemetryEventH\x00\x12/\n\x0e\x63ontext_shapes\x18\x06 \x01(\x0b\x32\x15.prefab.ContextShapesH\x00\x42\t\n\x07payload\"P\n\x0fTelemetryEvents\x12\x15\n\rinstance_hash\x18\x01 \x01(\t\x12&\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x16.prefab.TelemetryEvent\"*\n\x17TelemetryEventsResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\";\n\x0f\x45xampleContexts\x12(\n\x08\x65xamples\x18\x01 \x03(\x0b\x32\x16.prefab.ExampleContext\"K\n\x0e\x45xampleContext\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12&\n\ncontextSet\x18\x02 \x01(\x0b\x32\x12.prefab.ContextSet\"F\n\x0b\x43lientStats\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x1b\n\x13\x64ropped_event_count\x18\x03 \x01(\x04\"}\n\x06Schema\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12.\n\x0bschema_type\x18\x02 \x01(\x0e\x32\x19.prefab.Schema.SchemaType\"3\n\nSchemaType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03ZOD\x10\x01\x12\x0f\n\x0bJSON_SCHEMA\x10\x02*:\n\x0eProvidedSource\x12\x1b\n\x17PROVIDED_SOURCE_NOT_SET\x10\x00\x12\x0b\n\x07\x45NV_VAR\x10\x01*\xa0\x01\n\nConfigType\x12\x17\n\x13NOT_SET_CONFIG_TYPE\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\x10\n\x0c\x46\x45\x41TURE_FLAG\x10\x02\x12\r\n\tLOG_LEVEL\x10\x03\x12\x0b\n\x07SEGMENT\x10\x04\x12\x14\n\x10LIMIT_DEFINITION\x10\x05\x12\x0b\n\x07\x44\x45LETED\x10\x06\x12\n\n\x06SCHEMA\x10\x07\x12\x10\n\x0cLOG_LEVEL_V2\x10\x08*a\n\x08LogLevel\x12\x15\n\x11NOT_SET_LOG_LEVEL\x10\x00\x12\t\n\x05TRACE\x10\x01\x12\t\n\x05\x44\x45\x42UG\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x08\n\x04WARN\x10\x05\x12\t\n\x05\x45RROR\x10\x06\x12\t\n\x05\x46\x41TAL\x10\t*G\n\tOnFailure\x12\x0b\n\x07NOT_SET\x10\x00\x12\x10\n\x0cLOG_AND_PASS\x10\x01\x12\x10\n\x0cLOG_AND_FAIL\x10\x02\x12\t\n\x05THROW\x10\x03\x42L\n\x13\x63loud.prefab.domainB\x06PrefabZ-github.com/prefab-cloud/prefab-cloud-go/protob\x06proto3"
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            pool = ::Google::Protobuf::DescriptorPool.generated_pool
         
     | 
| 
       11 
11 
     | 
    
         
             
            pool.add_serialized_file(descriptor_data)
         
     | 
    
        data/lib/reforge/client.rb
    CHANGED
    
    | 
         @@ -53,6 +53,10 @@ module Reforge 
     | 
|
| 
       53 
53 
     | 
    
         
             
                  @feature_flag_client ||= Reforge::FeatureFlagClient.new(self)
         
     | 
| 
       54 
54 
     | 
    
         
             
                end
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
      
 56 
     | 
    
         
            +
                def log_level_client
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @log_level_client ||= Reforge::LogLevelClient.new(self)
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
       56 
60 
     | 
    
         
             
                def context_shape_aggregator
         
     | 
| 
       57 
61 
     | 
    
         
             
                  return nil if @options.collect_max_shapes <= 0
         
     | 
| 
       58 
62 
     | 
    
         | 
| 
         @@ -1,43 +1,173 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
              class InternalLogger < SemanticLogger::Logger
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            module Reforge
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Internal logger for the Reforge SDK
         
     | 
| 
      
 5 
     | 
    
         
            +
              # Uses SemanticLogger if available, falls back to stdlib Logger
         
     | 
| 
      
 6 
     | 
    
         
            +
              class InternalLogger
         
     | 
| 
       4 
7 
     | 
    
         
             
                def initialize(klass)
         
     | 
| 
       5 
     | 
    
         
            -
                   
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
      
 8 
     | 
    
         
            +
                  @klass = klass
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @level_sym = nil # Track the symbol level for consistency
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  if defined?(SemanticLogger)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @logger = create_semantic_logger
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @using_semantic = true
         
     | 
| 
      
 14 
     | 
    
         
            +
                  else
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @logger = create_stdlib_logger
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @using_semantic = false
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # Track all instances regardless of logger type
         
     | 
| 
       7 
20 
     | 
    
         
             
                  instances << self
         
     | 
| 
       8 
21 
     | 
    
         
             
                end
         
     | 
| 
       9 
22 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                   
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
                # Log methods
         
     | 
| 
      
 24 
     | 
    
         
            +
                def trace(message = nil, &block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  log_message(:trace, message, &block)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def debug(message = nil, &block)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  log_message(:debug, message, &block)
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def info(message = nil, &block)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  log_message(:info, message, &block)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def warn(message = nil, &block)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  log_message(:warn, message, &block)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def error(message = nil, &block)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  log_message(:error, message, &block)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def fatal(message = nil, &block)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  log_message(:fatal, message, &block)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def level
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if @using_semantic
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @logger.level
         
     | 
| 
      
 51 
     | 
    
         
            +
                  else
         
     | 
| 
      
 52 
     | 
    
         
            +
                    # Return the symbol level we tracked, or map from Logger constant
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @level_sym || case @logger.level
         
     | 
| 
      
 54 
     | 
    
         
            +
                                 when Logger::DEBUG then :debug
         
     | 
| 
      
 55 
     | 
    
         
            +
                                 when Logger::INFO then :info
         
     | 
| 
      
 56 
     | 
    
         
            +
                                 when Logger::WARN then :warn
         
     | 
| 
      
 57 
     | 
    
         
            +
                                 when Logger::ERROR then :error
         
     | 
| 
      
 58 
     | 
    
         
            +
                                 when Logger::FATAL then :fatal
         
     | 
| 
      
 59 
     | 
    
         
            +
                                 else :warn
         
     | 
| 
      
 60 
     | 
    
         
            +
                                 end
         
     | 
| 
       17 
61 
     | 
    
         
             
                  end
         
     | 
| 
       18 
62 
     | 
    
         
             
                end
         
     | 
| 
       19 
63 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                def  
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
      
 64 
     | 
    
         
            +
                def level=(new_level)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  if @using_semantic
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @logger.level = new_level
         
     | 
| 
      
 67 
     | 
    
         
            +
                  else
         
     | 
| 
      
 68 
     | 
    
         
            +
                    # Track the symbol level for consistency
         
     | 
| 
      
 69 
     | 
    
         
            +
                    @level_sym = new_level
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    # Map symbol to Logger constant
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @logger.level = case new_level
         
     | 
| 
      
 73 
     | 
    
         
            +
                                   when :trace, :debug then Logger::DEBUG
         
     | 
| 
      
 74 
     | 
    
         
            +
                                   when :info then Logger::INFO
         
     | 
| 
      
 75 
     | 
    
         
            +
                                   when :warn then Logger::WARN
         
     | 
| 
      
 76 
     | 
    
         
            +
                                   when :error then Logger::ERROR
         
     | 
| 
      
 77 
     | 
    
         
            +
                                   when :fatal then Logger::FATAL
         
     | 
| 
      
 78 
     | 
    
         
            +
                                   else Logger::WARN
         
     | 
| 
      
 79 
     | 
    
         
            +
                                   end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
       22 
81 
     | 
    
         
             
                end
         
     | 
| 
       23 
82 
     | 
    
         | 
| 
       24 
83 
     | 
    
         
             
                # Our client outputs debug logging,
         
     | 
| 
       25 
84 
     | 
    
         
             
                # but if you aren't using Reforge logging this could be too chatty.
         
     | 
| 
       26 
85 
     | 
    
         
             
                # If you aren't using reforge log filter, only log warn level and above
         
     | 
| 
       27 
86 
     | 
    
         
             
                def self.using_reforge_log_filter!
         
     | 
| 
       28 
     | 
    
         
            -
                  @@instances 
     | 
| 
       29 
     | 
    
         
            -
                     
     | 
| 
      
 87 
     | 
    
         
            +
                  @@instances&.each do |logger|
         
     | 
| 
      
 88 
     | 
    
         
            +
                    logger.level = :trace
         
     | 
| 
       30 
89 
     | 
    
         
             
                  end
         
     | 
| 
       31 
90 
     | 
    
         
             
                end
         
     | 
| 
       32 
91 
     | 
    
         | 
| 
       33 
92 
     | 
    
         
             
                private
         
     | 
| 
       34 
93 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                def  
     | 
| 
       36 
     | 
    
         
            -
                   
     | 
| 
      
 94 
     | 
    
         
            +
                def create_semantic_logger
         
     | 
| 
      
 95 
     | 
    
         
            +
                  default_level = env_log_level || :warn
         
     | 
| 
      
 96 
     | 
    
         
            +
                  logger = SemanticLogger::Logger.new(@klass, default_level)
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                  # Wrap to prevent recursion
         
     | 
| 
      
 99 
     | 
    
         
            +
                  class << logger
         
     | 
| 
      
 100 
     | 
    
         
            +
                    def log(log, message = nil, progname = nil, &block)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      return if recurse_check[local_log_id]
         
     | 
| 
      
 102 
     | 
    
         
            +
                      recurse_check[local_log_id] = true
         
     | 
| 
      
 103 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 104 
     | 
    
         
            +
                        super(log, message, progname, &block)
         
     | 
| 
      
 105 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 106 
     | 
    
         
            +
                        recurse_check[local_log_id] = false
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                    def local_log_id
         
     | 
| 
      
 111 
     | 
    
         
            +
                      Thread.current.__id__
         
     | 
| 
      
 112 
     | 
    
         
            +
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    private
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    def recurse_check
         
     | 
| 
      
 117 
     | 
    
         
            +
                      @recurse_check ||= Concurrent::Map.new(initial_capacity: 2)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    end
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  logger
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                def create_stdlib_logger
         
     | 
| 
      
 125 
     | 
    
         
            +
                  require 'logger'
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # When using stdlib Logger (no SemanticLogger), write to $stderr only
         
     | 
| 
      
 127 
     | 
    
         
            +
                  # Tests use $logs for SemanticLogger-filtered output, not stdlib Logger
         
     | 
| 
      
 128 
     | 
    
         
            +
                  logger = Logger.new($stderr)
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  # When SemanticLogger is not available, default to :warn to match SemanticLogger behavior
         
     | 
| 
      
 131 
     | 
    
         
            +
                  default_level_sym = :warn
         
     | 
| 
      
 132 
     | 
    
         
            +
                  @level_sym = env_log_level || default_level_sym
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  logger.level = case @level_sym
         
     | 
| 
      
 135 
     | 
    
         
            +
                                when :trace, :debug then Logger::DEBUG
         
     | 
| 
      
 136 
     | 
    
         
            +
                                when :info then Logger::INFO
         
     | 
| 
      
 137 
     | 
    
         
            +
                                when :warn then Logger::WARN
         
     | 
| 
      
 138 
     | 
    
         
            +
                                when :error then Logger::ERROR
         
     | 
| 
      
 139 
     | 
    
         
            +
                                when :fatal then Logger::FATAL
         
     | 
| 
      
 140 
     | 
    
         
            +
                                else Logger::WARN
         
     | 
| 
      
 141 
     | 
    
         
            +
                                end
         
     | 
| 
      
 142 
     | 
    
         
            +
                  logger.progname = @klass.to_s
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  # Use a custom formatter that mimics SemanticLogger format
         
     | 
| 
      
 145 
     | 
    
         
            +
                  # SemanticLogger format: "ClassName -- Message"
         
     | 
| 
      
 146 
     | 
    
         
            +
                  # This helps tests that expect SemanticLogger-style output
         
     | 
| 
      
 147 
     | 
    
         
            +
                  logger.formatter = proc do |severity, datetime, progname, msg|
         
     | 
| 
      
 148 
     | 
    
         
            +
                    "#{progname} -- #{msg}\n"
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  logger
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                def env_log_level
         
     | 
| 
      
 155 
     | 
    
         
            +
                  level_str = ENV['REFORGE_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL']
         
     | 
| 
      
 156 
     | 
    
         
            +
                  level_str&.downcase&.to_sym
         
     | 
| 
       37 
157 
     | 
    
         
             
                end
         
     | 
| 
       38 
158 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                def  
     | 
| 
       40 
     | 
    
         
            -
                  @ 
     | 
| 
      
 159 
     | 
    
         
            +
                def log_message(level, message, &block)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  if @using_semantic
         
     | 
| 
      
 161 
     | 
    
         
            +
                    @logger.send(level, message, &block)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  else
         
     | 
| 
      
 163 
     | 
    
         
            +
                    # stdlib Logger doesn't have trace
         
     | 
| 
      
 164 
     | 
    
         
            +
                    level = :debug if level == :trace
         
     | 
| 
      
 165 
     | 
    
         
            +
                    @logger.send(level, message || block&.call)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
                end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                def instances
         
     | 
| 
      
 170 
     | 
    
         
            +
                  @@instances ||= []
         
     | 
| 
       41 
171 
     | 
    
         
             
                end
         
     | 
| 
       42 
172 
     | 
    
         
             
              end
         
     | 
| 
       43 
173 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Reforge
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Public LogLevel enum that maps to the underlying Prefab.Config.LogLevel
         
     | 
| 
      
 5 
     | 
    
         
            +
              module LogLevel
         
     | 
| 
      
 6 
     | 
    
         
            +
                TRACE = :trace
         
     | 
| 
      
 7 
     | 
    
         
            +
                DEBUG = :debug
         
     | 
| 
      
 8 
     | 
    
         
            +
                INFO = :info
         
     | 
| 
      
 9 
     | 
    
         
            +
                WARN = :warn
         
     | 
| 
      
 10 
     | 
    
         
            +
                ERROR = :error
         
     | 
| 
      
 11 
     | 
    
         
            +
                FATAL = :fatal
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # Map from PrefabProto::LogLevel enum symbols (uppercase) to our public LogLevel constants (lowercase)
         
     | 
| 
      
 14 
     | 
    
         
            +
                # When unwrapped, the proto returns uppercase symbols like :INFO, :DEBUG, etc.
         
     | 
| 
      
 15 
     | 
    
         
            +
                PROTO_SYMBOL_TO_LOG_LEVEL = {
         
     | 
| 
      
 16 
     | 
    
         
            +
                  :NOT_SET_LOG_LEVEL => DEBUG,
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :TRACE => TRACE,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :DEBUG => DEBUG,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :INFO => INFO,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :WARN => WARN,
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :ERROR => ERROR,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :FATAL => FATAL
         
     | 
| 
      
 23 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # Map from PrefabProto::LogLevel enum integer values to our public LogLevel constants
         
     | 
| 
      
 26 
     | 
    
         
            +
                PROTO_INT_TO_LOG_LEVEL = {
         
     | 
| 
      
 27 
     | 
    
         
            +
                  PrefabProto::LogLevel::NOT_SET_LOG_LEVEL => DEBUG,
         
     | 
| 
      
 28 
     | 
    
         
            +
                  PrefabProto::LogLevel::TRACE => TRACE,
         
     | 
| 
      
 29 
     | 
    
         
            +
                  PrefabProto::LogLevel::DEBUG => DEBUG,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  PrefabProto::LogLevel::INFO => INFO,
         
     | 
| 
      
 31 
     | 
    
         
            +
                  PrefabProto::LogLevel::WARN => WARN,
         
     | 
| 
      
 32 
     | 
    
         
            +
                  PrefabProto::LogLevel::ERROR => ERROR,
         
     | 
| 
      
 33 
     | 
    
         
            +
                  PrefabProto::LogLevel::FATAL => FATAL
         
     | 
| 
      
 34 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def self.from_proto(proto_log_level)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  case proto_log_level
         
     | 
| 
      
 38 
     | 
    
         
            +
                  when Symbol
         
     | 
| 
      
 39 
     | 
    
         
            +
                    PROTO_SYMBOL_TO_LOG_LEVEL.fetch(proto_log_level, DEBUG)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  when Integer
         
     | 
| 
      
 41 
     | 
    
         
            +
                    PROTO_INT_TO_LOG_LEVEL.fetch(proto_log_level, DEBUG)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  else
         
     | 
| 
      
 43 
     | 
    
         
            +
                    DEBUG
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,169 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Reforge
         
     | 
| 
      
 4 
     | 
    
         
            +
              class LogLevelClient
         
     | 
| 
      
 5 
     | 
    
         
            +
                LOG = Reforge::InternalLogger.new(self)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # Map from our LogLevel symbols to SemanticLogger numeric severity levels
         
     | 
| 
      
 8 
     | 
    
         
            +
                # SemanticLogger levels: trace=0, debug=1, info=2, warn=3, error=4, fatal=5
         
     | 
| 
      
 9 
     | 
    
         
            +
                SEMANTIC_LOGGER_LEVELS = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                  trace: 0,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  debug: 1,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  info: 2,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  warn: 3,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  error: 4,
         
     | 
| 
      
 15 
     | 
    
         
            +
                  fatal: 5
         
     | 
| 
      
 16 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def initialize(base_client)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @base_client = base_client
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # Map from Ruby stdlib Logger severity levels to our LogLevel symbols
         
     | 
| 
      
 23 
     | 
    
         
            +
                # Ruby Logger levels: DEBUG=0, INFO=1, WARN=2, ERROR=3, FATAL=4, UNKNOWN=5
         
     | 
| 
      
 24 
     | 
    
         
            +
                STDLIB_LOGGER_LEVELS = {
         
     | 
| 
      
 25 
     | 
    
         
            +
                  0 => :debug,  # Logger::DEBUG
         
     | 
| 
      
 26 
     | 
    
         
            +
                  1 => :info,   # Logger::INFO
         
     | 
| 
      
 27 
     | 
    
         
            +
                  2 => :warn,   # Logger::WARN
         
     | 
| 
      
 28 
     | 
    
         
            +
                  3 => :error,  # Logger::ERROR
         
     | 
| 
      
 29 
     | 
    
         
            +
                  4 => :fatal,  # Logger::FATAL
         
     | 
| 
      
 30 
     | 
    
         
            +
                  5 => :fatal   # Logger::UNKNOWN (treat as fatal)
         
     | 
| 
      
 31 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Check if a log message should be logged based on severity and logger path
         
     | 
| 
      
 34 
     | 
    
         
            +
                # @param severity [Integer] Logger severity level (0-5 for SemanticLogger, 0-5 for stdlib Logger)
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @param path [String] Logger path/name
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @return [Boolean] true if the message should be logged
         
     | 
| 
      
 37 
     | 
    
         
            +
                def should_log?(severity, path)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  configured_level = get_log_level(path)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  configured_severity = SEMANTIC_LOGGER_LEVELS[configured_level]
         
     | 
| 
      
 40 
     | 
    
         
            +
                  severity >= configured_severity
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # SemanticLogger filter integration
         
     | 
| 
      
 44 
     | 
    
         
            +
                # @param log [SemanticLogger::Log] The log entry to filter
         
     | 
| 
      
 45 
     | 
    
         
            +
                # @return [Boolean] true if the log should be output
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Note: This method requires semantic_logger gem to be installed
         
     | 
| 
      
 47 
     | 
    
         
            +
                def semantic_filter(log)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  unless defined?(SemanticLogger)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    LOG.warn "semantic_filter called but SemanticLogger is not loaded. Install the 'semantic_logger' gem to use this feature."
         
     | 
| 
      
 50 
     | 
    
         
            +
                    return true # Allow all logs through if SemanticLogger is not available
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  class_path = class_path_name(log.name)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  level = SemanticLogger::Levels.index(log.level)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  log.named_tags.merge!({ path: class_path })
         
     | 
| 
      
 56 
     | 
    
         
            +
                  should_log?(level, class_path)
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                # Returns a formatter proc for use with Ruby stdlib Logger
         
     | 
| 
      
 60 
     | 
    
         
            +
                # Usage:
         
     | 
| 
      
 61 
     | 
    
         
            +
                #   logger = Logger.new($stdout)
         
     | 
| 
      
 62 
     | 
    
         
            +
                #   logger.formatter = client.log_level_client.stdlib_formatter('MyApp')
         
     | 
| 
      
 63 
     | 
    
         
            +
                # @param logger_name [String] The name/path of the logger
         
     | 
| 
      
 64 
     | 
    
         
            +
                # @return [Proc] A formatter proc that respects dynamic log levels
         
     | 
| 
      
 65 
     | 
    
         
            +
                def stdlib_formatter(logger_name)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  proc do |severity, datetime, progname, msg|
         
     | 
| 
      
 67 
     | 
    
         
            +
                    # Convert Logger severity string to integer (DEBUG=0, INFO=1, WARN=2, ERROR=3, FATAL=4)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    severity_int = case severity
         
     | 
| 
      
 69 
     | 
    
         
            +
                                  when 'DEBUG' then 0
         
     | 
| 
      
 70 
     | 
    
         
            +
                                  when 'INFO' then 1
         
     | 
| 
      
 71 
     | 
    
         
            +
                                  when 'WARN' then 2
         
     | 
| 
      
 72 
     | 
    
         
            +
                                  when 'ERROR' then 3
         
     | 
| 
      
 73 
     | 
    
         
            +
                                  when 'FATAL', 'UNKNOWN' then 4
         
     | 
| 
      
 74 
     | 
    
         
            +
                                  else 1
         
     | 
| 
      
 75 
     | 
    
         
            +
                                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    # Check if we should log this message
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if should_log?(severity_int, logger_name)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      # Default formatting
         
     | 
| 
      
 80 
     | 
    
         
            +
                      "[#{datetime.strftime('%Y-%m-%d %H:%M:%S.%L')}] #{severity} -- #{progname}: #{msg}\n"
         
     | 
| 
      
 81 
     | 
    
         
            +
                    else
         
     | 
| 
      
 82 
     | 
    
         
            +
                      nil # Don't output the log
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                # Get the log level for a given logger name
         
     | 
| 
      
 88 
     | 
    
         
            +
                # Returns a LogLevel symbol (:trace, :debug, :info, :warn, :error, :fatal)
         
     | 
| 
      
 89 
     | 
    
         
            +
                # Defaults to :debug if no config is found
         
     | 
| 
      
 90 
     | 
    
         
            +
                def get_log_level(logger_name)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  logger_key = @base_client.options.logger_key
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  # If logger key is explicitly set to nil or empty, return default
         
     | 
| 
      
 94 
     | 
    
         
            +
                  if logger_key.nil? || logger_key.empty?
         
     | 
| 
      
 95 
     | 
    
         
            +
                    LOG.debug "logger_key is nil or empty, returning default log level DEBUG"
         
     | 
| 
      
 96 
     | 
    
         
            +
                    return Reforge::LogLevel::DEBUG
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  # Create the evaluation context
         
     | 
| 
      
 100 
     | 
    
         
            +
                  context = {
         
     | 
| 
      
 101 
     | 
    
         
            +
                    "reforge-sdk-logging" => {
         
     | 
| 
      
 102 
     | 
    
         
            +
                      "lang" => "ruby",
         
     | 
| 
      
 103 
     | 
    
         
            +
                      "logger-path" => logger_name
         
     | 
| 
      
 104 
     | 
    
         
            +
                    }
         
     | 
| 
      
 105 
     | 
    
         
            +
                  }
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  # Get the raw config to check its type first
         
     | 
| 
      
 108 
     | 
    
         
            +
                  raw_config = @base_client.config_client.resolver.raw(logger_key)
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                  if raw_config.nil?
         
     | 
| 
      
 111 
     | 
    
         
            +
                    LOG.debug "No raw config found for key '#{logger_key}', returning default DEBUG"
         
     | 
| 
      
 112 
     | 
    
         
            +
                    return Reforge::LogLevel::DEBUG
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                  # Verify it's a LOG_LEVEL_V2 config
         
     | 
| 
      
 116 
     | 
    
         
            +
                  if raw_config.config_type != :LOG_LEVEL_V2
         
     | 
| 
      
 117 
     | 
    
         
            +
                    LOG.warn "Config '#{logger_key}' is not a LOG_LEVEL_V2 config (type: #{raw_config.config_type}), returning default DEBUG"
         
     | 
| 
      
 118 
     | 
    
         
            +
                    return Reforge::LogLevel::DEBUG
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 122 
     | 
    
         
            +
                    # Evaluate the config with the context
         
     | 
| 
      
 123 
     | 
    
         
            +
                    evaluation = @base_client.config_client.send(:_get, logger_key, context)
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                    if evaluation.nil?
         
     | 
| 
      
 126 
     | 
    
         
            +
                      LOG.debug "No log level config found for key '#{logger_key}', returning default DEBUG"
         
     | 
| 
      
 127 
     | 
    
         
            +
                      return Reforge::LogLevel::DEBUG
         
     | 
| 
      
 128 
     | 
    
         
            +
                    end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                    # Get the unwrapped value - this returns a PrefabProto::LogLevel enum value
         
     | 
| 
      
 131 
     | 
    
         
            +
                    proto_log_level = evaluation.report_and_return(@base_client.evaluation_summary_aggregator)
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                    # Convert the proto LogLevel to our public LogLevel enum
         
     | 
| 
      
 134 
     | 
    
         
            +
                    Reforge::LogLevel.from_proto(proto_log_level)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 136 
     | 
    
         
            +
                    LOG.warn "Error getting log level for '#{logger_name}': #{e.message}"
         
     | 
| 
      
 137 
     | 
    
         
            +
                    LOG.debug e.backtrace.join("\n")
         
     | 
| 
      
 138 
     | 
    
         
            +
                    Reforge::LogLevel::DEBUG
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                private
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                # Convert a logger class name to a path format
         
     | 
| 
      
 145 
     | 
    
         
            +
                # e.g., "MyApp::MyClass" becomes "my_app.my_class"
         
     | 
| 
      
 146 
     | 
    
         
            +
                def class_path_name(class_name)
         
     | 
| 
      
 147 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 148 
     | 
    
         
            +
                    log_class = Object.const_get(class_name)
         
     | 
| 
      
 149 
     | 
    
         
            +
                    if log_class.respond_to?(:superclass) && log_class.superclass != Object
         
     | 
| 
      
 150 
     | 
    
         
            +
                      underscore("#{log_class.superclass.name}.#{log_class.name}")
         
     | 
| 
      
 151 
     | 
    
         
            +
                    else
         
     | 
| 
      
 152 
     | 
    
         
            +
                      underscore(log_class.name.to_s)
         
     | 
| 
      
 153 
     | 
    
         
            +
                    end.gsub(/[^a-z_]/i, '.')
         
     | 
| 
      
 154 
     | 
    
         
            +
                  rescue NameError
         
     | 
| 
      
 155 
     | 
    
         
            +
                    # If we can't resolve the constant, just underscore the name
         
     | 
| 
      
 156 
     | 
    
         
            +
                    underscore(class_name.to_s).gsub(/[^a-z_]/i, '.')
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                # Convert CamelCase to snake_case
         
     | 
| 
      
 161 
     | 
    
         
            +
                def underscore(string)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  string.gsub(/::/, '/').
         
     | 
| 
      
 163 
     | 
    
         
            +
                    gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
         
     | 
| 
      
 164 
     | 
    
         
            +
                    gsub(/([a-z\d])([A-Z])/, '\1_\2').
         
     | 
| 
      
 165 
     | 
    
         
            +
                    tr("-", "_").
         
     | 
| 
      
 166 
     | 
    
         
            +
                    downcase
         
     | 
| 
      
 167 
     | 
    
         
            +
                end
         
     | 
| 
      
 168 
     | 
    
         
            +
              end
         
     | 
| 
      
 169 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/reforge/options.rb
    CHANGED
    
    | 
         @@ -18,6 +18,7 @@ module Reforge 
     | 
|
| 
       18 
18 
     | 
    
         
             
                attr_reader :global_context
         
     | 
| 
       19 
19 
     | 
    
         
             
                attr_accessor :is_fork
         
     | 
| 
       20 
20 
     | 
    
         
             
                attr_reader :symbolize_json_names
         
     | 
| 
      
 21 
     | 
    
         
            +
                attr_reader :logger_key
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
                module ON_INITIALIZATION_FAILURE
         
     | 
| 
       23 
24 
     | 
    
         
             
                  RAISE = :raise
         
     | 
| 
         @@ -65,7 +66,8 @@ module Reforge 
     | 
|
| 
       65 
66 
     | 
    
         
             
                  x_datafile: nil, # DEPRECATED in favor of `datafile`
         
     | 
| 
       66 
67 
     | 
    
         
             
                  x_use_local_cache: false,
         
     | 
| 
       67 
68 
     | 
    
         
             
                  symbolize_json_names: false,
         
     | 
| 
       68 
     | 
    
         
            -
                  global_context: {}
         
     | 
| 
      
 69 
     | 
    
         
            +
                  global_context: {},
         
     | 
| 
      
 70 
     | 
    
         
            +
                  logger_key: 'log-levels.default'
         
     | 
| 
       69 
71 
     | 
    
         
             
                )
         
     | 
| 
       70 
72 
     | 
    
         
             
                  @sdk_key = sdk_key
         
     | 
| 
       71 
73 
     | 
    
         
             
                  @namespace = namespace
         
     | 
| 
         @@ -90,6 +92,7 @@ module Reforge 
     | 
|
| 
       90 
92 
     | 
    
         
             
                  @is_fork = false
         
     | 
| 
       91 
93 
     | 
    
         
             
                  @global_context = global_context
         
     | 
| 
       92 
94 
     | 
    
         
             
                  @symbolize_json_names = symbolize_json_names
         
     | 
| 
      
 95 
     | 
    
         
            +
                  @logger_key = logger_key
         
     | 
| 
       93 
96 
     | 
    
         | 
| 
       94 
97 
     | 
    
         
             
                  # defaults that may be overridden by context_upload_mode
         
     | 
| 
       95 
98 
     | 
    
         
             
                  @collect_shapes = false
         
     | 
    
        data/lib/reforge/reforge.rb
    CHANGED
    
    | 
         @@ -49,6 +49,13 @@ module Reforge 
     | 
|
| 
       49 
49 
     | 
    
         
             
              end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
51 
     | 
    
         
             
              def self.log_filter
         
     | 
| 
      
 52 
     | 
    
         
            +
                unless defined?(SemanticLogger)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # SemanticLogger is optional - return a pass-through filter
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # Only log debug message if explicitly enabled
         
     | 
| 
      
 55 
     | 
    
         
            +
                  LOG.debug 'log_filter called but SemanticLogger is not available. Install the semantic_logger gem to use this feature.' if ENV['REFORGE_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL'] == 'debug'
         
     | 
| 
      
 56 
     | 
    
         
            +
                  return Proc.new { |log| true } # Pass through all logs
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
       52 
59 
     | 
    
         
             
                InternalLogger.using_reforge_log_filter!
         
     | 
| 
       53 
60 
     | 
    
         
             
                return Proc.new do |log|
         
     | 
| 
       54 
61 
     | 
    
         
             
                  bootstrap_log_level(log)
         
     | 
| 
         @@ -60,6 +67,8 @@ module Reforge 
     | 
|
| 
       60 
67 
     | 
    
         
             
              end
         
     | 
| 
       61 
68 
     | 
    
         | 
| 
       62 
69 
     | 
    
         
             
              def self.bootstrap_log_level(log)
         
     | 
| 
      
 70 
     | 
    
         
            +
                return true unless defined?(SemanticLogger)
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
       63 
72 
     | 
    
         
             
                level = ENV['REFORGE_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL'] ? ENV['REFORGE_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL'].downcase.to_sym : :warn
         
     | 
| 
       64 
73 
     | 
    
         
             
                SemanticLogger::Levels.index(level) <= SemanticLogger::Levels.index(log.level)
         
     | 
| 
       65 
74 
     | 
    
         
             
              end
         
     | 
    
        data/lib/sdk-reforge.rb
    CHANGED
    
    | 
         @@ -5,7 +5,12 @@ module Reforge 
     | 
|
| 
       5 
5 
     | 
    
         
             
              VERSION = File.read(File.dirname(__FILE__) + '/../VERSION').strip
         
     | 
| 
       6 
6 
     | 
    
         
             
            end
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 8 
     | 
    
         
            +
            begin
         
     | 
| 
      
 9 
     | 
    
         
            +
              require 'semantic_logger'
         
     | 
| 
      
 10 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 11 
     | 
    
         
            +
              # semantic_logger is optional - only needed for dynamic log level filtering
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       9 
14 
     | 
    
         
             
            require 'reforge/internal_logger'
         
     | 
| 
       10 
15 
     | 
    
         
             
            require 'concurrent/atomics'
         
     | 
| 
       11 
16 
     | 
    
         
             
            require 'concurrent'
         
     | 
| 
         @@ -49,6 +54,8 @@ require 'reforge/client' 
     | 
|
| 
       49 
54 
     | 
    
         
             
            require 'reforge/config_client_presenter'
         
     | 
| 
       50 
55 
     | 
    
         
             
            require 'reforge/config_client'
         
     | 
| 
       51 
56 
     | 
    
         
             
            require 'reforge/feature_flag_client'
         
     | 
| 
      
 57 
     | 
    
         
            +
            require 'reforge/log_level'
         
     | 
| 
      
 58 
     | 
    
         
            +
            require 'reforge/log_level_client'
         
     | 
| 
       52 
59 
     | 
    
         
             
            require 'reforge/reforge'
         
     | 
| 
       53 
60 
     | 
    
         
             
            require 'reforge/murmer3'
         
     | 
| 
       54 
61 
     | 
    
         
             
            require 'reforge/javascript_stub'
         
     | 
    
        data/sdk-reforge.gemspec
    CHANGED
    
    | 
         @@ -2,16 +2,16 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            # DO NOT EDIT THIS FILE DIRECTLY
         
     | 
| 
       3 
3 
     | 
    
         
             
            # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
         
     | 
| 
       4 
4 
     | 
    
         
             
            # -*- encoding: utf-8 -*-
         
     | 
| 
       5 
     | 
    
         
            -
            # stub: sdk-reforge 1. 
     | 
| 
      
 5 
     | 
    
         
            +
            # stub: sdk-reforge 1.12.0 ruby lib
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       8 
8 
     | 
    
         
             
              s.name = "sdk-reforge".freeze
         
     | 
| 
       9 
     | 
    
         
            -
              s.version = "1. 
     | 
| 
      
 9 
     | 
    
         
            +
              s.version = "1.12.0"
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
         
     | 
| 
       12 
12 
     | 
    
         
             
              s.require_paths = ["lib".freeze]
         
     | 
| 
       13 
13 
     | 
    
         
             
              s.authors = ["Jeff Dwyer".freeze]
         
     | 
| 
       14 
     | 
    
         
            -
              s.date = "2025-10- 
     | 
| 
      
 14 
     | 
    
         
            +
              s.date = "2025-10-31"
         
     | 
| 
       15 
15 
     | 
    
         
             
              s.description = "Feature Flags, Live Config as a service".freeze
         
     | 
| 
       16 
16 
     | 
    
         
             
              s.email = "jeff.dwyer@reforge.com.cloud".freeze
         
     | 
| 
       17 
17 
     | 
    
         
             
              s.extra_rdoc_files = [
         
     | 
| 
         @@ -20,6 +20,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       20 
20 
     | 
    
         
             
                "README.md"
         
     | 
| 
       21 
21 
     | 
    
         
             
              ]
         
     | 
| 
       22 
22 
     | 
    
         
             
              s.files = [
         
     | 
| 
      
 23 
     | 
    
         
            +
                ".DS_Store",
         
     | 
| 
       23 
24 
     | 
    
         
             
                ".envrc.sample",
         
     | 
| 
       24 
25 
     | 
    
         
             
                ".github/CODEOWNERS",
         
     | 
| 
       25 
26 
     | 
    
         
             
                ".github/pull_request_template.md",
         
     | 
| 
         @@ -73,6 +74,8 @@ Gem::Specification.new do |s| 
     | 
|
| 
       73 
74 
     | 
    
         
             
                "lib/reforge/internal_logger.rb",
         
     | 
| 
       74 
75 
     | 
    
         
             
                "lib/reforge/javascript_stub.rb",
         
     | 
| 
       75 
76 
     | 
    
         
             
                "lib/reforge/local_config_parser.rb",
         
     | 
| 
      
 77 
     | 
    
         
            +
                "lib/reforge/log_level.rb",
         
     | 
| 
      
 78 
     | 
    
         
            +
                "lib/reforge/log_level_client.rb",
         
     | 
| 
       76 
79 
     | 
    
         
             
                "lib/reforge/murmer3.rb",
         
     | 
| 
       77 
80 
     | 
    
         
             
                "lib/reforge/options.rb",
         
     | 
| 
       78 
81 
     | 
    
         
             
                "lib/reforge/periodic_sync.rb",
         
     | 
| 
         @@ -116,6 +119,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       116 
119 
     | 
    
         
             
                "test/test_internal_logger.rb",
         
     | 
| 
       117 
120 
     | 
    
         
             
                "test/test_javascript_stub.rb",
         
     | 
| 
       118 
121 
     | 
    
         
             
                "test/test_local_config_parser.rb",
         
     | 
| 
      
 122 
     | 
    
         
            +
                "test/test_log_level_client.rb",
         
     | 
| 
       119 
123 
     | 
    
         
             
                "test/test_logger_initialization.rb",
         
     | 
| 
       120 
124 
     | 
    
         
             
                "test/test_options.rb",
         
     | 
| 
       121 
125 
     | 
    
         
             
                "test/test_prefab.rb",
         
     | 
| 
         @@ -138,7 +142,6 @@ Gem::Specification.new do |s| 
     | 
|
| 
       138 
142 
     | 
    
         
             
              s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
         
     | 
| 
       139 
143 
     | 
    
         
             
              s.add_runtime_dependency(%q<uuid>.freeze, [">= 0"])
         
     | 
| 
       140 
144 
     | 
    
         
             
              s.add_runtime_dependency(%q<activesupport>.freeze, [">= 4"])
         
     | 
| 
       141 
     | 
    
         
            -
              s.add_runtime_dependency(%q<semantic_logger>.freeze, ["!= 4.16.0"])
         
     | 
| 
       142 
145 
     | 
    
         
             
              s.add_development_dependency(%q<allocation_stats>.freeze, [">= 0"])
         
     | 
| 
       143 
146 
     | 
    
         
             
              s.add_development_dependency(%q<benchmark-ips>.freeze, [">= 0"])
         
     | 
| 
       144 
147 
     | 
    
         
             
              s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
         
     | 
| 
         @@ -9,8 +9,11 @@ module CommonHelpers 
     | 
|
| 
       9 
9 
     | 
    
         
             
                $logs = StringIO.new
         
     | 
| 
       10 
10 
     | 
    
         
             
                Reforge::Context.global_context.clear
         
     | 
| 
       11 
11 
     | 
    
         
             
                Reforge::Context.default_context.clear
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                SemanticLogger 
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                if defined?(SemanticLogger)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  SemanticLogger.add_appender(io: $logs, filter: Reforge.log_filter)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  SemanticLogger.sync!
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
       14 
17 
     | 
    
         
             
              end
         
     | 
| 
       15 
18 
     | 
    
         | 
| 
       16 
19 
     | 
    
         
             
              def teardown
         
     | 
| 
         @@ -0,0 +1,264 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class TestLogLevelClient < Minitest::Test
         
     | 
| 
      
 6 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 7 
     | 
    
         
            +
                super
         
     | 
| 
      
 8 
     | 
    
         
            +
                @options = Reforge::Options.new(
         
     | 
| 
      
 9 
     | 
    
         
            +
                  prefab_datasources: Reforge::Options::DATASOURCES::LOCAL_ONLY,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  logger_key: 'test.log.level.key'
         
     | 
| 
      
 11 
     | 
    
         
            +
                )
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                @client = Reforge::Client.new(@options)
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def test_get_log_level_returns_debug_when_no_config_exists
         
     | 
| 
      
 17 
     | 
    
         
            +
                log_level = @client.log_level_client.get_log_level('MyApp::MyClass')
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert_equal :debug, log_level
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def test_get_log_level_with_log_level_v2_config
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Create a LOG_LEVEL_V2 config
         
     | 
| 
      
 23 
     | 
    
         
            +
                config = PrefabProto::Config.new(
         
     | 
| 
      
 24 
     | 
    
         
            +
                  key: 'test.log.level.key',
         
     | 
| 
      
 25 
     | 
    
         
            +
                  id: 1,
         
     | 
| 
      
 26 
     | 
    
         
            +
                  config_type: PrefabProto::ConfigType::LOG_LEVEL_V2,
         
     | 
| 
      
 27 
     | 
    
         
            +
                  value_type: PrefabProto::Config::ValueType::LOG_LEVEL,
         
     | 
| 
      
 28 
     | 
    
         
            +
                  rows: [
         
     | 
| 
      
 29 
     | 
    
         
            +
                    PrefabProto::ConfigRow.new(
         
     | 
| 
      
 30 
     | 
    
         
            +
                      values: [
         
     | 
| 
      
 31 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 32 
     | 
    
         
            +
                          criteria: [
         
     | 
| 
      
 33 
     | 
    
         
            +
                            PrefabProto::Criterion.new(
         
     | 
| 
      
 34 
     | 
    
         
            +
                              operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
         
     | 
| 
      
 35 
     | 
    
         
            +
                              property_name: 'reforge-sdk-logging.logger-path',
         
     | 
| 
      
 36 
     | 
    
         
            +
                              value_to_match: PrefabProto::ConfigValue.new(
         
     | 
| 
      
 37 
     | 
    
         
            +
                                string_list: PrefabProto::StringList.new(values: ['MyApp::DebugClass'])
         
     | 
| 
      
 38 
     | 
    
         
            +
                              )
         
     | 
| 
      
 39 
     | 
    
         
            +
                            )
         
     | 
| 
      
 40 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 41 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 43 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 44 
     | 
    
         
            +
                          criteria: [
         
     | 
| 
      
 45 
     | 
    
         
            +
                            PrefabProto::Criterion.new(
         
     | 
| 
      
 46 
     | 
    
         
            +
                              operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
         
     | 
| 
      
 47 
     | 
    
         
            +
                              property_name: 'reforge-sdk-logging.logger-path',
         
     | 
| 
      
 48 
     | 
    
         
            +
                              value_to_match: PrefabProto::ConfigValue.new(
         
     | 
| 
      
 49 
     | 
    
         
            +
                                string_list: PrefabProto::StringList.new(values: ['MyApp::InfoClass'])
         
     | 
| 
      
 50 
     | 
    
         
            +
                              )
         
     | 
| 
      
 51 
     | 
    
         
            +
                            )
         
     | 
| 
      
 52 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 53 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::INFO)
         
     | 
| 
      
 54 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 55 
     | 
    
         
            +
                        # Default case - WARN for everything else
         
     | 
| 
      
 56 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 57 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::WARN)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        )
         
     | 
| 
      
 59 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 60 
     | 
    
         
            +
                    )
         
     | 
| 
      
 61 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 62 
     | 
    
         
            +
                )
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                # Load the config into the resolver
         
     | 
| 
      
 65 
     | 
    
         
            +
                @client.config_client.resolver.instance_variable_get(:@config_loader).set(config, :test)
         
     | 
| 
      
 66 
     | 
    
         
            +
                @client.config_client.resolver.update
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                # Test that we get DEBUG for MyApp::DebugClass
         
     | 
| 
      
 69 
     | 
    
         
            +
                log_level = @client.log_level_client.get_log_level('MyApp::DebugClass')
         
     | 
| 
      
 70 
     | 
    
         
            +
                assert_equal :debug, log_level
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                # Test that we get INFO for MyApp::InfoClass
         
     | 
| 
      
 73 
     | 
    
         
            +
                log_level = @client.log_level_client.get_log_level('MyApp::InfoClass')
         
     | 
| 
      
 74 
     | 
    
         
            +
                assert_equal :info, log_level
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                # Test that we get WARN for anything else (default)
         
     | 
| 
      
 77 
     | 
    
         
            +
                log_level = @client.log_level_client.get_log_level('MyApp::OtherClass')
         
     | 
| 
      
 78 
     | 
    
         
            +
                assert_equal :warn, log_level
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              def test_get_log_level_with_all_log_levels
         
     | 
| 
      
 82 
     | 
    
         
            +
                # Create a LOG_LEVEL_V2 config with all log levels
         
     | 
| 
      
 83 
     | 
    
         
            +
                config = PrefabProto::Config.new(
         
     | 
| 
      
 84 
     | 
    
         
            +
                  key: 'test.log.level.key',
         
     | 
| 
      
 85 
     | 
    
         
            +
                  id: 1,
         
     | 
| 
      
 86 
     | 
    
         
            +
                  config_type: PrefabProto::ConfigType::LOG_LEVEL_V2,
         
     | 
| 
      
 87 
     | 
    
         
            +
                  value_type: PrefabProto::Config::ValueType::LOG_LEVEL,
         
     | 
| 
      
 88 
     | 
    
         
            +
                  rows: [
         
     | 
| 
      
 89 
     | 
    
         
            +
                    PrefabProto::ConfigRow.new(
         
     | 
| 
      
 90 
     | 
    
         
            +
                      values: [
         
     | 
| 
      
 91 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 92 
     | 
    
         
            +
                          criteria: [
         
     | 
| 
      
 93 
     | 
    
         
            +
                            PrefabProto::Criterion.new(
         
     | 
| 
      
 94 
     | 
    
         
            +
                              operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
         
     | 
| 
      
 95 
     | 
    
         
            +
                              property_name: 'reforge-sdk-logging.logger-path',
         
     | 
| 
      
 96 
     | 
    
         
            +
                              value_to_match: PrefabProto::ConfigValue.new(
         
     | 
| 
      
 97 
     | 
    
         
            +
                                string_list: PrefabProto::StringList.new(values: ['TraceLogger'])
         
     | 
| 
      
 98 
     | 
    
         
            +
                              )
         
     | 
| 
      
 99 
     | 
    
         
            +
                            )
         
     | 
| 
      
 100 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 101 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::TRACE)
         
     | 
| 
      
 102 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 103 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 104 
     | 
    
         
            +
                          criteria: [
         
     | 
| 
      
 105 
     | 
    
         
            +
                            PrefabProto::Criterion.new(
         
     | 
| 
      
 106 
     | 
    
         
            +
                              operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
         
     | 
| 
      
 107 
     | 
    
         
            +
                              property_name: 'reforge-sdk-logging.logger-path',
         
     | 
| 
      
 108 
     | 
    
         
            +
                              value_to_match: PrefabProto::ConfigValue.new(
         
     | 
| 
      
 109 
     | 
    
         
            +
                                string_list: PrefabProto::StringList.new(values: ['ErrorLogger'])
         
     | 
| 
      
 110 
     | 
    
         
            +
                              )
         
     | 
| 
      
 111 
     | 
    
         
            +
                            )
         
     | 
| 
      
 112 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 113 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::ERROR)
         
     | 
| 
      
 114 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 115 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 116 
     | 
    
         
            +
                          criteria: [
         
     | 
| 
      
 117 
     | 
    
         
            +
                            PrefabProto::Criterion.new(
         
     | 
| 
      
 118 
     | 
    
         
            +
                              operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
         
     | 
| 
      
 119 
     | 
    
         
            +
                              property_name: 'reforge-sdk-logging.logger-path',
         
     | 
| 
      
 120 
     | 
    
         
            +
                              value_to_match: PrefabProto::ConfigValue.new(
         
     | 
| 
      
 121 
     | 
    
         
            +
                                string_list: PrefabProto::StringList.new(values: ['FatalLogger'])
         
     | 
| 
      
 122 
     | 
    
         
            +
                              )
         
     | 
| 
      
 123 
     | 
    
         
            +
                            )
         
     | 
| 
      
 124 
     | 
    
         
            +
                          ],
         
     | 
| 
      
 125 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::FATAL)
         
     | 
| 
      
 126 
     | 
    
         
            +
                        )
         
     | 
| 
      
 127 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 128 
     | 
    
         
            +
                    )
         
     | 
| 
      
 129 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 130 
     | 
    
         
            +
                )
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                # Load the config into the resolver
         
     | 
| 
      
 133 
     | 
    
         
            +
                @client.config_client.resolver.instance_variable_get(:@config_loader).set(config, :test)
         
     | 
| 
      
 134 
     | 
    
         
            +
                @client.config_client.resolver.update
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                # Test all log levels
         
     | 
| 
      
 137 
     | 
    
         
            +
                assert_equal :trace, @client.log_level_client.get_log_level('TraceLogger')
         
     | 
| 
      
 138 
     | 
    
         
            +
                assert_equal :error, @client.log_level_client.get_log_level('ErrorLogger')
         
     | 
| 
      
 139 
     | 
    
         
            +
                assert_equal :fatal, @client.log_level_client.get_log_level('FatalLogger')
         
     | 
| 
      
 140 
     | 
    
         
            +
              end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
              def test_get_log_level_returns_debug_when_logger_key_is_nil
         
     | 
| 
      
 143 
     | 
    
         
            +
                options = Reforge::Options.new(
         
     | 
| 
      
 144 
     | 
    
         
            +
                  prefab_datasources: Reforge::Options::DATASOURCES::LOCAL_ONLY,
         
     | 
| 
      
 145 
     | 
    
         
            +
                  logger_key: nil
         
     | 
| 
      
 146 
     | 
    
         
            +
                )
         
     | 
| 
      
 147 
     | 
    
         
            +
                client = Reforge::Client.new(options)
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                log_level = client.log_level_client.get_log_level('MyApp::MyClass')
         
     | 
| 
      
 150 
     | 
    
         
            +
                assert_equal :debug, log_level
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
              def test_get_log_level_returns_debug_when_logger_key_is_empty
         
     | 
| 
      
 154 
     | 
    
         
            +
                options = Reforge::Options.new(
         
     | 
| 
      
 155 
     | 
    
         
            +
                  prefab_datasources: Reforge::Options::DATASOURCES::LOCAL_ONLY,
         
     | 
| 
      
 156 
     | 
    
         
            +
                  logger_key: ''
         
     | 
| 
      
 157 
     | 
    
         
            +
                )
         
     | 
| 
      
 158 
     | 
    
         
            +
                client = Reforge::Client.new(options)
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                log_level = client.log_level_client.get_log_level('MyApp::MyClass')
         
     | 
| 
      
 161 
     | 
    
         
            +
                assert_equal :debug, log_level
         
     | 
| 
      
 162 
     | 
    
         
            +
              end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              def test_get_log_level_returns_debug_when_config_is_wrong_type
         
     | 
| 
      
 165 
     | 
    
         
            +
                # Create a regular CONFIG type instead of LOG_LEVEL_V2
         
     | 
| 
      
 166 
     | 
    
         
            +
                config = PrefabProto::Config.new(
         
     | 
| 
      
 167 
     | 
    
         
            +
                  key: 'test.log.level.key',
         
     | 
| 
      
 168 
     | 
    
         
            +
                  id: 1,
         
     | 
| 
      
 169 
     | 
    
         
            +
                  config_type: PrefabProto::ConfigType::CONFIG,
         
     | 
| 
      
 170 
     | 
    
         
            +
                  value_type: PrefabProto::Config::ValueType::STRING,
         
     | 
| 
      
 171 
     | 
    
         
            +
                  rows: [
         
     | 
| 
      
 172 
     | 
    
         
            +
                    PrefabProto::ConfigRow.new(
         
     | 
| 
      
 173 
     | 
    
         
            +
                      values: [
         
     | 
| 
      
 174 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 175 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(string: 'not a log level')
         
     | 
| 
      
 176 
     | 
    
         
            +
                        )
         
     | 
| 
      
 177 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 178 
     | 
    
         
            +
                    )
         
     | 
| 
      
 179 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 180 
     | 
    
         
            +
                )
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                # Load the config into the resolver
         
     | 
| 
      
 183 
     | 
    
         
            +
                @client.config_client.resolver.instance_variable_get(:@config_loader).set(config, :test)
         
     | 
| 
      
 184 
     | 
    
         
            +
                @client.config_client.resolver.update
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                log_level = @client.log_level_client.get_log_level('MyApp::MyClass')
         
     | 
| 
      
 187 
     | 
    
         
            +
                assert_equal :debug, log_level
         
     | 
| 
      
 188 
     | 
    
         
            +
                assert_logged [/Config 'test.log.level.key' is not a LOG_LEVEL_V2 config/]
         
     | 
| 
      
 189 
     | 
    
         
            +
              end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
              def test_log_level_enum_from_proto
         
     | 
| 
      
 192 
     | 
    
         
            +
                assert_equal :trace, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::TRACE)
         
     | 
| 
      
 193 
     | 
    
         
            +
                assert_equal :debug, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::DEBUG)
         
     | 
| 
      
 194 
     | 
    
         
            +
                assert_equal :info, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::INFO)
         
     | 
| 
      
 195 
     | 
    
         
            +
                assert_equal :warn, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::WARN)
         
     | 
| 
      
 196 
     | 
    
         
            +
                assert_equal :error, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::ERROR)
         
     | 
| 
      
 197 
     | 
    
         
            +
                assert_equal :fatal, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::FATAL)
         
     | 
| 
      
 198 
     | 
    
         
            +
                assert_equal :debug, Reforge::LogLevel.from_proto(PrefabProto::LogLevel::NOT_SET_LOG_LEVEL)
         
     | 
| 
      
 199 
     | 
    
         
            +
              end
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
              def test_default_logger_key
         
     | 
| 
      
 202 
     | 
    
         
            +
                options = Reforge::Options.new(
         
     | 
| 
      
 203 
     | 
    
         
            +
                  prefab_datasources: Reforge::Options::DATASOURCES::LOCAL_ONLY
         
     | 
| 
      
 204 
     | 
    
         
            +
                )
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                assert_equal 'log-levels.default', options.logger_key
         
     | 
| 
      
 207 
     | 
    
         
            +
              end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
              def test_should_log_with_different_severities
         
     | 
| 
      
 210 
     | 
    
         
            +
                # Create a LOG_LEVEL_V2 config set to INFO
         
     | 
| 
      
 211 
     | 
    
         
            +
                config = PrefabProto::Config.new(
         
     | 
| 
      
 212 
     | 
    
         
            +
                  key: 'test.log.level.key',
         
     | 
| 
      
 213 
     | 
    
         
            +
                  id: 1,
         
     | 
| 
      
 214 
     | 
    
         
            +
                  config_type: PrefabProto::ConfigType::LOG_LEVEL_V2,
         
     | 
| 
      
 215 
     | 
    
         
            +
                  value_type: PrefabProto::Config::ValueType::LOG_LEVEL,
         
     | 
| 
      
 216 
     | 
    
         
            +
                  rows: [
         
     | 
| 
      
 217 
     | 
    
         
            +
                    PrefabProto::ConfigRow.new(
         
     | 
| 
      
 218 
     | 
    
         
            +
                      values: [
         
     | 
| 
      
 219 
     | 
    
         
            +
                        PrefabProto::ConditionalValue.new(
         
     | 
| 
      
 220 
     | 
    
         
            +
                          value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::INFO)
         
     | 
| 
      
 221 
     | 
    
         
            +
                        )
         
     | 
| 
      
 222 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 223 
     | 
    
         
            +
                    )
         
     | 
| 
      
 224 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 225 
     | 
    
         
            +
                )
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                @client.config_client.resolver.instance_variable_get(:@config_loader).set(config, :test)
         
     | 
| 
      
 228 
     | 
    
         
            +
                @client.config_client.resolver.update
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                # SemanticLogger levels: trace=0, debug=1, info=2, warn=3, error=4, fatal=5
         
     | 
| 
      
 231 
     | 
    
         
            +
                # With INFO level set, we should log INFO (2) and above, but not DEBUG (1) or TRACE (0)
         
     | 
| 
      
 232 
     | 
    
         
            +
                assert_equal false, @client.log_level_client.should_log?(0, 'MyApp::MyClass'), 'TRACE should not log'
         
     | 
| 
      
 233 
     | 
    
         
            +
                assert_equal false, @client.log_level_client.should_log?(1, 'MyApp::MyClass'), 'DEBUG should not log'
         
     | 
| 
      
 234 
     | 
    
         
            +
                assert_equal true, @client.log_level_client.should_log?(2, 'MyApp::MyClass'), 'INFO should log'
         
     | 
| 
      
 235 
     | 
    
         
            +
                assert_equal true, @client.log_level_client.should_log?(3, 'MyApp::MyClass'), 'WARN should log'
         
     | 
| 
      
 236 
     | 
    
         
            +
                assert_equal true, @client.log_level_client.should_log?(4, 'MyApp::MyClass'), 'ERROR should log'
         
     | 
| 
      
 237 
     | 
    
         
            +
                assert_equal true, @client.log_level_client.should_log?(5, 'MyApp::MyClass'), 'FATAL should log'
         
     | 
| 
      
 238 
     | 
    
         
            +
              end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
              def test_class_path_name_conversion
         
     | 
| 
      
 241 
     | 
    
         
            +
                client = @client.log_level_client
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
                # Test underscore conversion
         
     | 
| 
      
 244 
     | 
    
         
            +
                assert_equal 'my_app.my_class', client.send(:class_path_name, 'MyApp::MyClass')
         
     | 
| 
      
 245 
     | 
    
         
            +
              end
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
              def test_underscore
         
     | 
| 
      
 248 
     | 
    
         
            +
                client = @client.log_level_client
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                assert_equal 'my_app/my_class', client.send(:underscore, 'MyApp::MyClass')
         
     | 
| 
      
 251 
     | 
    
         
            +
                assert_equal 'html_parser', client.send(:underscore, 'HTMLParser')
         
     | 
| 
      
 252 
     | 
    
         
            +
                assert_equal 'my_simple_class', client.send(:underscore, 'MySimpleClass')
         
     | 
| 
      
 253 
     | 
    
         
            +
              end
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
              def test_semantic_logger_levels_mapping
         
     | 
| 
      
 256 
     | 
    
         
            +
                # Verify our SEMANTIC_LOGGER_LEVELS constant matches expectations
         
     | 
| 
      
 257 
     | 
    
         
            +
                assert_equal 0, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:trace]
         
     | 
| 
      
 258 
     | 
    
         
            +
                assert_equal 1, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:debug]
         
     | 
| 
      
 259 
     | 
    
         
            +
                assert_equal 2, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:info]
         
     | 
| 
      
 260 
     | 
    
         
            +
                assert_equal 3, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:warn]
         
     | 
| 
      
 261 
     | 
    
         
            +
                assert_equal 4, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:error]
         
     | 
| 
      
 262 
     | 
    
         
            +
                assert_equal 5, Reforge::LogLevelClient::SEMANTIC_LOGGER_LEVELS[:fatal]
         
     | 
| 
      
 263 
     | 
    
         
            +
              end
         
     | 
| 
      
 264 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sdk-reforge
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.12.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Jeff Dwyer
         
     | 
| 
       8 
8 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       9 
9 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       10 
     | 
    
         
            -
            date: 2025-10- 
     | 
| 
      
 10 
     | 
    
         
            +
            date: 2025-10-31 00:00:00.000000000 Z
         
     | 
| 
       11 
11 
     | 
    
         
             
            dependencies:
         
     | 
| 
       12 
12 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       13 
13 
     | 
    
         
             
              name: concurrent-ruby
         
     | 
| 
         @@ -113,20 +113,6 @@ dependencies: 
     | 
|
| 
       113 
113 
     | 
    
         
             
                - - ">="
         
     | 
| 
       114 
114 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       115 
115 
     | 
    
         
             
                    version: '4'
         
     | 
| 
       116 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       117 
     | 
    
         
            -
              name: semantic_logger
         
     | 
| 
       118 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       119 
     | 
    
         
            -
                requirements:
         
     | 
| 
       120 
     | 
    
         
            -
                - - "!="
         
     | 
| 
       121 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       122 
     | 
    
         
            -
                    version: 4.16.0
         
     | 
| 
       123 
     | 
    
         
            -
              type: :runtime
         
     | 
| 
       124 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       125 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       126 
     | 
    
         
            -
                requirements:
         
     | 
| 
       127 
     | 
    
         
            -
                - - "!="
         
     | 
| 
       128 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       129 
     | 
    
         
            -
                    version: 4.16.0
         
     | 
| 
       130 
116 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       131 
117 
     | 
    
         
             
              name: allocation_stats
         
     | 
| 
       132 
118 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -220,6 +206,7 @@ extra_rdoc_files: 
     | 
|
| 
       220 
206 
     | 
    
         
             
            - LICENSE.txt
         
     | 
| 
       221 
207 
     | 
    
         
             
            - README.md
         
     | 
| 
       222 
208 
     | 
    
         
             
            files:
         
     | 
| 
      
 209 
     | 
    
         
            +
            - ".DS_Store"
         
     | 
| 
       223 
210 
     | 
    
         
             
            - ".envrc.sample"
         
     | 
| 
       224 
211 
     | 
    
         
             
            - ".github/CODEOWNERS"
         
     | 
| 
       225 
212 
     | 
    
         
             
            - ".github/pull_request_template.md"
         
     | 
| 
         @@ -273,6 +260,8 @@ files: 
     | 
|
| 
       273 
260 
     | 
    
         
             
            - lib/reforge/internal_logger.rb
         
     | 
| 
       274 
261 
     | 
    
         
             
            - lib/reforge/javascript_stub.rb
         
     | 
| 
       275 
262 
     | 
    
         
             
            - lib/reforge/local_config_parser.rb
         
     | 
| 
      
 263 
     | 
    
         
            +
            - lib/reforge/log_level.rb
         
     | 
| 
      
 264 
     | 
    
         
            +
            - lib/reforge/log_level_client.rb
         
     | 
| 
       276 
265 
     | 
    
         
             
            - lib/reforge/murmer3.rb
         
     | 
| 
       277 
266 
     | 
    
         
             
            - lib/reforge/options.rb
         
     | 
| 
       278 
267 
     | 
    
         
             
            - lib/reforge/periodic_sync.rb
         
     | 
| 
         @@ -316,6 +305,7 @@ files: 
     | 
|
| 
       316 
305 
     | 
    
         
             
            - test/test_internal_logger.rb
         
     | 
| 
       317 
306 
     | 
    
         
             
            - test/test_javascript_stub.rb
         
     | 
| 
       318 
307 
     | 
    
         
             
            - test/test_local_config_parser.rb
         
     | 
| 
      
 308 
     | 
    
         
            +
            - test/test_log_level_client.rb
         
     | 
| 
       319 
309 
     | 
    
         
             
            - test/test_logger_initialization.rb
         
     | 
| 
       320 
310 
     | 
    
         
             
            - test/test_options.rb
         
     | 
| 
       321 
311 
     | 
    
         
             
            - test/test_prefab.rb
         
     |