prefab-cloud-ruby 0.18.0 → 0.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9225ebaadf8be997d152b66cb58ff342d126bc5cfbe489511af4791d89dd5f7
4
- data.tar.gz: cbaf511c7aeaf0ef743b33c2ad00c40bd4d6c8ddba0a17ddff541afeb8e055d9
3
+ metadata.gz: f56ee15a73bef27dbb37cfbc4df7b1004543664ea7b5defc5ae6afbb738a4c23
4
+ data.tar.gz: 151d525aca5d58ee1098fed1f6e87037ee6b2cc8570985f2a922ec028cc3d394
5
5
  SHA512:
6
- metadata.gz: f00e343e6f3f7a7f11351409708979c4e02420eae8bf8d9520cdc58de464b682158b863bcab88b4583c469709c621f066bd8995e482963386b931c877bfd2b1f
7
- data.tar.gz: 5e51d64d2d5adc738e5f8438cd222ae3e4d9fc1f183a789d25486da7197b25c3263fff9a0fac9b33a9acffc169e035630e7a8cb8b3d3770e9e8b669d34b96f68
6
+ metadata.gz: 9d48de76dc679c635a9530625aa0feedd6ddb9193023b98e5c24247f6eded562e9ffcca770116dc5a1bc7dc60a0e7fad2f828f31b791c771c7d3aa587daf77bd
7
+ data.tar.gz: da2371a89c4886ac22d2ce5ef0b7b2e8b732aa8ac2600a699b1598cc1c9138c9a99e075df944d911f790f385ffea81c2b186aaf29d6b40ed7c5f05247d41d22b
data/Gemfile CHANGED
@@ -19,4 +19,5 @@ end
19
19
 
20
20
  group :test do
21
21
  gem "minitest"
22
+ gem "minitest-focus"
22
23
  end
data/Gemfile.lock CHANGED
@@ -30,7 +30,7 @@ GEM
30
30
  faraday (>= 0.8, < 2)
31
31
  hashie (~> 3.5, >= 3.5.2)
32
32
  oauth2 (~> 1.0)
33
- google-protobuf (3.21.4)
33
+ google-protobuf (3.21.9)
34
34
  googleapis-common-protos-types (1.3.0)
35
35
  google-protobuf (~> 3.14)
36
36
  grpc (1.43.1)
@@ -70,10 +70,12 @@ GEM
70
70
  rake (~> 13.0)
71
71
  mini_portile2 (2.8.0)
72
72
  minitest (5.16.2)
73
+ minitest-focus (1.3.1)
74
+ minitest (>= 4, < 6)
73
75
  multi_json (1.15.0)
74
76
  multi_xml (0.6.0)
75
77
  multipart-post (2.1.1)
76
- nokogiri (1.13.6)
78
+ nokogiri (1.13.9)
77
79
  mini_portile2 (~> 2.8.0)
78
80
  racc (~> 1.4)
79
81
  oauth2 (1.4.7)
@@ -86,7 +88,7 @@ GEM
86
88
  public_suffix (4.0.6)
87
89
  racc (1.6.0)
88
90
  rack (2.2.4)
89
- rake (13.0.3)
91
+ rake (13.0.6)
90
92
  rchardet (1.8.0)
91
93
  rdoc (6.3.3)
92
94
  ruby2_keywords (0.0.4)
@@ -119,6 +121,7 @@ DEPENDENCIES
119
121
  juwelier (~> 2.4.9)
120
122
  ld-eventsource
121
123
  minitest
124
+ minitest-focus
122
125
  rdoc
123
126
  simplecov
124
127
  thin
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # prefab-cloud-ruby
2
- Ruby Client for Prefab RateLimits, FeatureFlags, Config as a Service: https://www.prefab.cloud
2
+ Ruby Client for Prefab FeatureFlags, Config as a Service: https://www.prefab.cloud
3
3
 
4
4
  ```ruby
5
5
  client = Prefab::Client.new
@@ -16,11 +16,9 @@ puts @feature_flags.feature_is_on? "MyFeature", "user:1123"
16
16
  ```
17
17
  See full documentation https://www.prefab.cloud/documentation/installation
18
18
 
19
-
20
19
  ## Supports
21
20
 
22
21
  * [FeatureFlags](https://www.prefab.cloud/documentation/feature_flags) as a Service
23
- * [RateLimits](https://www.prefab.cloud/documentation/basic_rate_limits)
24
22
  * Millions of individual limits sharing the same policies
25
23
  * WebUI for tweaking limits & feature flags
26
24
  * Infinite retention for [deduplication workflows](https://www.prefab.cloud/documentation/once_and_only_once)
@@ -44,15 +42,19 @@ end
44
42
 
45
43
  ## Logging & Debugging
46
44
  In classpath or ~/.prefab.overrides.config.yaml set
47
- ```log-level.prefab: debug```
45
+
46
+ ```
47
+ log-level:
48
+ cloud.prefab: debug
49
+ ```
48
50
 
49
51
  To debug issues before this config file has been read, set env var
50
52
  ```
51
- PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL = debug
53
+ PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL=debug
52
54
  ```
53
55
 
54
56
  ## Contributing to prefab-cloud-ruby
55
-
57
+
56
58
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
57
59
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
58
60
  * Fork the project.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.18.0
1
+ 0.19.0
data/lib/prefab/client.rb CHANGED
@@ -47,10 +47,11 @@ module Prefab
47
47
  end
48
48
 
49
49
  def log
50
- @logger_client ||= Prefab::LoggerClient.new(@options.logdev, formatter: @options.log_formatter)
50
+ @logger_client ||= Prefab::LoggerClient.new(@options.logdev, formatter: @options.log_formatter,
51
+ prefix: @options.log_prefix)
51
52
  end
52
53
 
53
- def log_internal(level, msg, path = "prefab")
54
+ def log_internal(level, msg, path = nil)
54
55
  log.log_internal msg, path, nil, level
55
56
  end
56
57
 
@@ -189,7 +189,7 @@ module Prefab
189
189
  if @config_loader.highwater_mark > starting_highwater_mark
190
190
  @base_client.log_internal Logger::INFO, "Found new checkpoint with highwater id #{@config_loader.highwater_mark} from #{source} in project #{project_id} environment: #{project_env_id} and namespace: '#{@namespace}'"
191
191
  else
192
- @base_client.log_internal Logger::DEBUG, "Checkpoint with highwater id #{@config_loader.highwater_mark} from #{source}. No changes.", "prefab.config_client.load_configs"
192
+ @base_client.log_internal Logger::DEBUG, "Checkpoint with highwater id #{@config_loader.highwater_mark} from #{source}. No changes.", "load_configs"
193
193
  end
194
194
  @base_client.stats.increment("prefab.config.checkpoint.load")
195
195
  @config_resolver.update
@@ -237,7 +237,7 @@ module Prefab
237
237
  @streaming_thread = SSE::Client.new(url,
238
238
  headers: headers,
239
239
  read_timeout: SSE_READ_TIMEOUT,
240
- logger: Prefab::InternalLogger.new("prefab.config.sse", @base_client.log)) do |client|
240
+ logger: Prefab::SseLogger.new(@base_client.log)) do |client|
241
241
  client.on_event do |event|
242
242
  configs = Prefab::Configs.decode(Base64.decode64(event.data))
243
243
  load_configs(configs, :sse)
@@ -18,7 +18,8 @@ module Prefab
18
18
  def to_s
19
19
  str = "\n"
20
20
  @lock.with_read_lock do
21
- @local_store.each do |k, v|
21
+ @local_store.keys.sort.each do |k|
22
+ v = @local_store[k]
22
23
  elements = [k.slice(0..49).ljust(50)]
23
24
  if v.nil?
24
25
  elements << "tombstone"
@@ -5,6 +5,7 @@ module Prefab
5
5
  SEP = "."
6
6
  BASE_KEY = "log-level"
7
7
  UNKNOWN_PATH = "unknown."
8
+ INTERNAL_PREFIX = "cloud.prefab.client"
8
9
 
9
10
  LOG_LEVEL_LOOKUPS = {
10
11
  Prefab::LogLevel::NOT_SET_LOG_LEVEL => Logger::DEBUG,
@@ -16,24 +17,32 @@ module Prefab
16
17
  Prefab::LogLevel::FATAL => Logger::FATAL
17
18
  }
18
19
 
19
- def initialize(logdev, formatter: nil)
20
+ def initialize(logdev, formatter: nil, prefix: nil)
20
21
  super(logdev)
21
22
  self.formatter = formatter
22
23
  @config_client = BootstrappingConfigClient.new
23
- @silences = Concurrent::Map.new(:initial_capacity => 2)
24
+ @silences = Concurrent::Map.new(initial_capacity: 2)
25
+ @prefix = prefix
24
26
  end
25
27
 
26
- def add(severity, message = nil, progname = nil)
27
- loc = caller_locations(1, 1)[0]
28
- add_internal(severity, message, progname, loc)
28
+ def add(severity, message = nil, progname = nil, loc, &block)
29
+ path = get_loc_path(loc)
30
+ path = "#{@prefix}#{@prefix && '.'}#{path}"
31
+
32
+ log(message, path, progname, severity, &block)
29
33
  end
30
34
 
31
- def add_internal(severity, message = nil, progname = nil, loc, &block)
32
- path = get_loc_path(loc)
33
- log_internal(message, path, progname, severity, &block)
35
+ def log_internal(message, path = nil, progname, severity, &block)
36
+ if path
37
+ path = "#{INTERNAL_PREFIX}.#{path}"
38
+ else
39
+ path = INTERNAL_PREFIX
40
+ end
41
+
42
+ log(message, path, progname, severity, &block)
34
43
  end
35
44
 
36
- def log_internal(message, path, progname, severity, &block)
45
+ def log(message, path, progname, severity, &block)
37
46
  level = level_of(path)
38
47
  progname = "#{path}: #{progname}"
39
48
  severity ||= Logger::UNKNOWN
@@ -57,23 +66,23 @@ module Prefab
57
66
  end
58
67
 
59
68
  def debug(progname = nil, &block)
60
- add_internal(DEBUG, nil, progname, caller_locations(1, 1)[0], &block)
69
+ add(DEBUG, nil, progname, caller_locations(1, 1)[0], &block)
61
70
  end
62
71
 
63
72
  def info(progname = nil, &block)
64
- add_internal(INFO, nil, progname, caller_locations(1, 1)[0], &block)
73
+ add(INFO, nil, progname, caller_locations(1, 1)[0], &block)
65
74
  end
66
75
 
67
76
  def warn(progname = nil, &block)
68
- add_internal(WARN, nil, progname, caller_locations(1, 1)[0], &block)
77
+ add(WARN, nil, progname, caller_locations(1, 1)[0], &block)
69
78
  end
70
79
 
71
80
  def error(progname = nil, &block)
72
- add_internal(ERROR, nil, progname, caller_locations(1, 1)[0], &block)
81
+ add(ERROR, nil, progname, caller_locations(1, 1)[0], &block)
73
82
  end
74
83
 
75
84
  def fatal(progname = nil, &block)
76
- add_internal(FATAL, nil, progname, caller_locations(1, 1)[0], &block)
85
+ add(FATAL, nil, progname, caller_locations(1, 1)[0], &block)
77
86
  end
78
87
 
79
88
  def debug?
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Prefab
3
4
  class Options
4
5
  attr_reader :api_key
5
6
  attr_reader :logdev
7
+ attr_reader :log_prefix
6
8
  attr_reader :log_formatter
7
9
  attr_reader :stats
8
10
  attr_reader :shared_cache
@@ -40,6 +42,7 @@ module Prefab
40
42
  shared_cache: NoopCache.new, # Something that quacks like Rails.cache ideally memcached
41
43
  namespace: "",
42
44
  log_formatter: DEFAULT_LOG_FORMATTER,
45
+ log_prefix: nil,
43
46
  prefab_api_url: ENV["PREFAB_API_URL"] || 'https://api.prefab.cloud',
44
47
  prefab_grpc_url: ENV["PREFAB_GRPC_URL"] || 'grpc.prefab.cloud:443',
45
48
  on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
@@ -59,6 +62,7 @@ module Prefab
59
62
  @shared_cache = shared_cache
60
63
  @namespace = namespace
61
64
  @log_formatter = log_formatter
65
+ @log_prefix = log_prefix
62
66
  @prefab_api_url = prefab_api_url
63
67
  @prefab_grpc_url = prefab_grpc_url
64
68
  @on_no_default = on_no_default
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module Prefab
3
+ class SseLogger < InternalLogger
4
+ def initialize(logger)
5
+ super("sse", logger)
6
+ end
7
+
8
+ # The SSE::Client warns on a perfectly normal stream disconnect, recast to info
9
+ def warn(progname = nil, &block)
10
+ @logger.log_internal yield, @path, progname, INFO
11
+ end
12
+ end
13
+ end
@@ -13,6 +13,7 @@ require 'prefab/errors/missing_default_error'
13
13
  require 'prefab_services_pb'
14
14
  require 'prefab/options'
15
15
  require 'prefab/internal_logger'
16
+ require 'prefab/sse_logger'
16
17
  require 'prefab/config_helper'
17
18
  require 'prefab/config_loader'
18
19
  require 'prefab/config_resolver'
@@ -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: prefab-cloud-ruby 0.18.0 ruby lib
5
+ # stub: prefab-cloud-ruby 0.19.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.18.0"
9
+ s.version = "0.19.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 = "2022-10-14"
14
+ s.date = "2022-11-19"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  "lib/prefab/noop_stats.rb",
51
51
  "lib/prefab/options.rb",
52
52
  "lib/prefab/ratelimit_client.rb",
53
+ "lib/prefab/sse_logger.rb",
53
54
  "lib/prefab_pb.rb",
54
55
  "lib/prefab_services_pb.rb",
55
56
  "prefab-cloud-ruby.gemspec",
data/test/test_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'minitest/autorun'
3
+ require "minitest/focus"
3
4
  require 'prefab-cloud-ruby'
4
5
 
5
6
  class MockBaseClient
data/test/test_logger.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'test_helper'
3
4
 
4
5
  class TestCLogger < Minitest::Test
@@ -69,19 +70,19 @@ class TestCLogger < Minitest::Test
69
70
  end
70
71
 
71
72
  def test_log_internal
72
- logger, mock_logdev = mock_logger_expecting /W, \[.*\] WARN -- test.path: : test message/
73
+ logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- cloud.prefab.client.test.path: : test message/)
73
74
  logger.log_internal("test message", "test.path", "", Logger::WARN)
74
75
  mock_logdev.verify
75
76
  end
76
77
 
77
78
  def test_log_internal_unknown
78
- logger, mock_logdev = mock_logger_expecting /A, \[.*\] ANY -- test.path: : test message/
79
+ logger, mock_logdev = mock_logger_expecting(/A, \[.*\] ANY -- cloud.prefab.client.test.path: : test message/)
79
80
  logger.log_internal("test message", "test.path", "", Logger::UNKNOWN)
80
81
  mock_logdev.verify
81
82
  end
82
83
 
83
84
  def test_log_internal_silencing
84
- logger, mock_logdev = mock_logger_expecting /W, \[.*\] WARN -- test.path: : should log/, calls: 2
85
+ logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- cloud.prefab.client.test.path: : should log/, calls: 2)
85
86
  logger.silence do
86
87
  logger.log_internal("should not log", "test.path", "", Logger::WARN)
87
88
  end
@@ -89,6 +90,45 @@ class TestCLogger < Minitest::Test
89
90
  mock_logdev.verify
90
91
  end
91
92
 
93
+ def test_log
94
+ logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- test.path: : test message/)
95
+ logger.log("test message", "test.path", "", Logger::WARN)
96
+ mock_logdev.verify
97
+ end
98
+
99
+ def test_log_unknown
100
+ logger, mock_logdev = mock_logger_expecting(/A, \[.*\] ANY -- test.path: : test message/)
101
+ logger.log("test message", "test.path", "", Logger::UNKNOWN)
102
+ mock_logdev.verify
103
+ end
104
+
105
+ def test_log_silencing
106
+ logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- test.path: : should log/, calls: 2)
107
+ logger.silence do
108
+ logger.log("should not log", "test.path", "", Logger::WARN)
109
+ end
110
+ logger.log("should log", "test.path", "", Logger::WARN)
111
+ mock_logdev.verify
112
+ end
113
+
114
+ def test_logging_with_prefix
115
+ prefix = 'my.own.prefix'
116
+ message = 'this is a test'
117
+
118
+ io = StringIO.new
119
+ options = Prefab::Options.new(logdev: io, log_prefix: prefix, prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY)
120
+ prefab = Prefab::Client.new(options)
121
+
122
+ prefixed_logger = prefab.log
123
+ prefixed_logger.error message
124
+
125
+ assert_logged io.string, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_prefix", message
126
+ end
127
+
128
+ def assert_logged(log_line, level, path, message)
129
+ assert_match(/#{level} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]?\d+: #{path}: #{message}\n/, log_line)
130
+ end
131
+
92
132
  def mock_logger_expecting pattern, configs = {}, calls: 1
93
133
  mock_logdev = Minitest::Mock.new
94
134
  mock_logdev.expect :write, nil do |arg|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-14 00:00:00.000000000 Z
11
+ date: 2022-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -237,6 +237,7 @@ files:
237
237
  - lib/prefab/noop_stats.rb
238
238
  - lib/prefab/options.rb
239
239
  - lib/prefab/ratelimit_client.rb
240
+ - lib/prefab/sse_logger.rb
240
241
  - lib/prefab_pb.rb
241
242
  - lib/prefab_services_pb.rb
242
243
  - prefab-cloud-ruby.gemspec