berkeley_library-logging 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d520b09c106d1976a6d47efb671ba9c9ee8696f573e4aeb2571cdd1706744ae
4
- data.tar.gz: f801c8ee42f5e4cfee28f4148775b2142d3dfe26bb0f6e3633292bb7cd5ef747
3
+ metadata.gz: 91d0f1a398e99a9e138f90946025b7d5576cda6a4b6e4e8c137b77ec8febbd2f
4
+ data.tar.gz: 1300926d8af70a24e6fff33e3ac1e8af79c428e7c35302fab335d255f713d7a1
5
5
  SHA512:
6
- metadata.gz: 3ecb69bb4608198f67eed2b4215ddc105096f86a469b504f72ff331ef3380616afe83c9fe0a63f375f09453f7d23eca8a8032b6e8452db8ae84811ad079e996f
7
- data.tar.gz: f9c681893d8e25c2e1588fa5fa51b44db09cf8c782bf650a9b4606b9ffa26f380a6678155a23692025f149791684ec2201e1ec41c9c90bd8ea2c1ea39f957aba
6
+ metadata.gz: 2271582ebc293b95a3f9dc18c9c922b780abf1ab1636f549f9ac1093a4b72dabd8a6c224bd51e53be7b128b0f65759dd639bef744f7586659b98fcbd4eb19431
7
+ data.tar.gz: 874db3c599bfa7a1a00d9b15c35bc85120f1ed573ba5088c99c83bc12ef81ea1ab8e5c2fd081996c6ac684a0c2befc573de57547c951111b6e9e41c726847e64
data/.idea/logging.iml CHANGED
@@ -11,17 +11,17 @@
11
11
  </content>
12
12
  <orderEntry type="jdk" jdkName="RVM: ruby-2.7.4" jdkType="RUBY_SDK" />
13
13
  <orderEntry type="sourceFolder" forTests="false" />
14
- <orderEntry type="library" scope="PROVIDED" name="actioncable (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
15
- <orderEntry type="library" scope="PROVIDED" name="actionmailbox (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
16
- <orderEntry type="library" scope="PROVIDED" name="actionmailer (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="actionpack (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="actiontext (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="actionview (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="activejob (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="activemodel (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="activerecord (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="activestorage (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
14
+ <orderEntry type="library" scope="PROVIDED" name="actioncable (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="actionmailbox (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="actionmailer (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="actionpack (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="actiontext (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="actionview (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="activejob (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="activemodel (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="activerecord (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="activestorage (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
25
25
  <orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.3.0, RVM: ruby-2.7.4) [gem]" level="application" />
26
26
  <orderEntry type="library" scope="PROVIDED" name="ansi (v1.5.0, RVM: ruby-2.7.4) [gem]" level="application" />
27
27
  <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -29,7 +29,7 @@
29
29
  <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
30
30
  <orderEntry type="library" scope="PROVIDED" name="bundle-audit (v0.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
31
31
  <orderEntry type="library" scope="PROVIDED" name="bundler (v2.2.14, RVM: ruby-2.7.4) [gem]" level="application" />
32
- <orderEntry type="library" scope="PROVIDED" name="bundler-audit (v0.8.0, RVM: ruby-2.7.4) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="bundler-audit (v0.9.0.1, RVM: ruby-2.7.4) [gem]" level="application" />
33
33
  <orderEntry type="library" scope="PROVIDED" name="ci_reporter (v2.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
34
34
  <orderEntry type="library" scope="PROVIDED" name="ci_reporter_rspec (v1.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
35
35
  <orderEntry type="library" scope="PROVIDED" name="colorize (v0.8.1, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -39,7 +39,7 @@
39
39
  <orderEntry type="library" scope="PROVIDED" name="docile (v1.4.0, RVM: ruby-2.7.4) [gem]" level="application" />
40
40
  <orderEntry type="library" scope="PROVIDED" name="dotenv (v2.7.6, RVM: ruby-2.7.4) [gem]" level="application" />
41
41
  <orderEntry type="library" scope="PROVIDED" name="erubi (v1.10.0, RVM: ruby-2.7.4) [gem]" level="application" />
42
- <orderEntry type="library" scope="PROVIDED" name="ffi (v1.15.3, RVM: ruby-2.7.4) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="ffi (v1.15.4, RVM: ruby-2.7.4) [gem]" level="application" />
43
43
  <orderEntry type="library" scope="PROVIDED" name="globalid (v0.5.2, RVM: ruby-2.7.4) [gem]" level="application" />
44
44
  <orderEntry type="library" scope="PROVIDED" name="i18n (v1.8.10, RVM: ruby-2.7.4) [gem]" level="application" />
45
45
  <orderEntry type="library" scope="PROVIDED" name="io-console (v0.5.9, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -48,23 +48,23 @@
48
48
  <orderEntry type="library" scope="PROVIDED" name="lograge (v0.11.2, RVM: ruby-2.7.4) [gem]" level="application" />
49
49
  <orderEntry type="library" scope="PROVIDED" name="loofah (v2.12.0, RVM: ruby-2.7.4) [gem]" level="application" />
50
50
  <orderEntry type="library" scope="PROVIDED" name="mail (v2.7.1, RVM: ruby-2.7.4) [gem]" level="application" />
51
- <orderEntry type="library" scope="PROVIDED" name="marcel (v1.0.1, RVM: ruby-2.7.4) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="marcel (v1.0.2, RVM: ruby-2.7.4) [gem]" level="application" />
52
52
  <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
53
- <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.1.1, RVM: ruby-2.7.4) [gem]" level="application" />
54
54
  <orderEntry type="library" scope="PROVIDED" name="minitest (v5.14.4, RVM: ruby-2.7.4) [gem]" level="application" />
55
55
  <orderEntry type="library" scope="PROVIDED" name="nio4r (v2.5.8, RVM: ruby-2.7.4) [gem]" level="application" />
56
- <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.12.3, RVM: ruby-2.7.4) [gem]" level="application" />
57
- <orderEntry type="library" scope="PROVIDED" name="oj (v3.13.2, RVM: ruby-2.7.4) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.12.4, RVM: ruby-2.7.4) [gem]" level="application" />
57
+ <orderEntry type="library" scope="PROVIDED" name="oj (v3.13.7, RVM: ruby-2.7.4) [gem]" level="application" />
58
58
  <orderEntry type="library" scope="PROVIDED" name="ougai (v1.9.1, RVM: ruby-2.7.4) [gem]" level="application" />
59
- <orderEntry type="library" scope="PROVIDED" name="parallel (v1.20.1, RVM: ruby-2.7.4) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="parallel (v1.21.0, RVM: ruby-2.7.4) [gem]" level="application" />
60
60
  <orderEntry type="library" scope="PROVIDED" name="parser (v3.0.2.0, RVM: ruby-2.7.4) [gem]" level="application" />
61
61
  <orderEntry type="library" scope="PROVIDED" name="racc (v1.5.2, RVM: ruby-2.7.4) [gem]" level="application" />
62
62
  <orderEntry type="library" scope="PROVIDED" name="rack (v2.2.3, RVM: ruby-2.7.4) [gem]" level="application" />
63
63
  <orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
64
- <orderEntry type="library" scope="PROVIDED" name="rails (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="rails (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
65
65
  <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, RVM: ruby-2.7.4) [gem]" level="application" />
66
- <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
67
- <orderEntry type="library" scope="PROVIDED" name="railties (v6.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
67
+ <orderEntry type="library" scope="PROVIDED" name="railties (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
68
68
  <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
69
69
  <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, RVM: ruby-2.7.4) [gem]" level="application" />
70
70
  <orderEntry type="library" scope="PROVIDED" name="rb-fsevent (v0.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -89,10 +89,10 @@
89
89
  <orderEntry type="library" scope="PROVIDED" name="simplecov_json_formatter (v0.1.3, RVM: ruby-2.7.4) [gem]" level="application" />
90
90
  <orderEntry type="library" scope="PROVIDED" name="sprockets (v4.0.2, RVM: ruby-2.7.4) [gem]" level="application" />
91
91
  <orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.2, RVM: ruby-2.7.4) [gem]" level="application" />
92
- <orderEntry type="library" scope="PROVIDED" name="terminal-table (v3.0.1, RVM: ruby-2.7.4) [gem]" level="application" />
92
+ <orderEntry type="library" scope="PROVIDED" name="terminal-table (v3.0.2, RVM: ruby-2.7.4) [gem]" level="application" />
93
93
  <orderEntry type="library" scope="PROVIDED" name="thor (v1.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
94
94
  <orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.4, RVM: ruby-2.7.4) [gem]" level="application" />
95
- <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v1.7.0, RVM: ruby-2.7.4) [gem]" level="application" />
95
+ <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v1.8.0, RVM: ruby-2.7.4) [gem]" level="application" />
96
96
  <orderEntry type="library" scope="PROVIDED" name="websocket-driver (v0.7.5, RVM: ruby-2.7.4) [gem]" level="application" />
97
97
  <orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.5, RVM: ruby-2.7.4) [gem]" level="application" />
98
98
  <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -110,7 +110,7 @@
110
110
  <RakeTaskImpl description="Remove artifacts directory" fullCommand="clean" id="clean" />
111
111
  <RakeTaskImpl description="Run all specs in spec directory, with coverage" fullCommand="coverage" id="coverage" />
112
112
  <RakeTaskImpl description="Clean, check, build gem" fullCommand="default" id="default" />
113
- <RakeTaskImpl description="Build berkeley_library-logging.gemspec as berkeley_library-logging-0.2.0.gem" fullCommand="gem" id="gem" />
113
+ <RakeTaskImpl description="Build berkeley_library-logging.gemspec as berkeley_library-logging-0.2.3.gem" fullCommand="gem" id="gem" />
114
114
  <RakeTaskImpl description="Run RuboCop" fullCommand="rubocop" id="rubocop" />
115
115
  <RakeTaskImpl id="rubocop">
116
116
  <subtasks>
data/.simplecov CHANGED
@@ -1,15 +1,3 @@
1
1
  SimpleCov.start 'rails' do
2
2
  add_filter 'module_info.rb'
3
-
4
- if ENV['GITHUB_ACTION']
5
- formatter SimpleCov::Formatter::SimpleFormatter
6
- else
7
- # TODO: figure out why this doesn't work in CI
8
- require 'simplecov-rcov'
9
- coverage_dir 'artifacts'
10
-
11
- SimpleCov.collate Dir['artifacts/simplecov/**/.resultset.json'] do
12
- formatter SimpleCov::Formatter::RcovFormatter
13
- end
14
- end
15
3
  end
data/CHANGES.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 0.2.4 (2021-11-02)
2
+
3
+ - Rails event logs now include the following, in addition to the
4
+ headers already logged:
5
+
6
+ - `request.origin`
7
+ - `request.base_url`
8
+ - `request.x_csrf_token`
9
+ - `params[:authenticity_token]`
10
+
1
11
  # 0.2.3 (2021-09-02)
2
12
 
3
13
  - JSON formatter now strips all ANSI 7-bit C1 escapes from strings
data/artifacts/.keep ADDED
File without changes
@@ -2,6 +2,19 @@ module BerkeleyLibrary
2
2
  module Logging
3
3
  module Events
4
4
  class << self
5
+ LOGGED_REQUEST_ATTRIBUTES = %i[origin base_url x_csrf_token].freeze
6
+ LOGGED_PARAMETERS = [:authenticity_token].freeze
7
+ LOGGED_HEADERS = {
8
+ # yes, RFC 2616 uses a variant spelling for 'referrer', it's a known issue
9
+ # https://tools.ietf.org/html/rfc2616#section-14.36
10
+ referer: 'HTTP_REFERER',
11
+ request_id: 'action_dispatch.request_id',
12
+ remote_ip: 'action_dispatch.remote_ip',
13
+ remote_addr: 'REMOTE_ADDR',
14
+ x_forwarded_for: 'HTTP_X_FORWARDED_FOR',
15
+ forwarded: 'HTTP_FORWARDED' # RFC 7239
16
+ }.freeze
17
+
5
18
  def extract_data_for_lograge
6
19
  ->(event) { extract_event_data(event) }
7
20
  end
@@ -9,29 +22,50 @@ module BerkeleyLibrary
9
22
  private
10
23
 
11
24
  def extract_event_data(event)
12
- event_data = { time: Time.now }
13
- extracted_headers = extract_headers(event)
14
- event_data.merge(extracted_headers)
25
+ { time: Time.now }.tap do |event_data|
26
+ headers = extract_headers(event)
27
+ event_data.merge!(headers)
28
+
29
+ request_attributes = extract_request_attributes(event)
30
+ event_data.merge!(request_attributes)
31
+
32
+ param_values = extract_param_values(event)
33
+ event_data.merge!(param_values)
34
+ end
35
+ end
36
+
37
+ def extract_param_values(event)
38
+ return {} unless (params = event.payload[:params])
39
+
40
+ LOGGED_PARAMETERS.each_with_object({}) do |param, values|
41
+ next unless (param_val = params[param])
42
+
43
+ values[param] = param_val
44
+ end
45
+ end
46
+
47
+ def extract_request_attributes(event)
48
+ return {} unless (request = event.payload[:request])
49
+
50
+ LOGGED_REQUEST_ATTRIBUTES.each_with_object({}) do |attr, values|
51
+ next unless request.respond_to?(attr)
52
+ next unless (attr_val = request.send(attr))
53
+
54
+ values[attr] = attr_val
55
+ end
15
56
  end
16
57
 
17
58
  def extract_headers(event)
18
59
  return {} unless (headers = event.payload[:headers])
19
60
 
20
- extracted_headers = {
21
- # yes, RFC 2616 uses a variant spelling for 'referrer', it's a known issue
22
- # https://tools.ietf.org/html/rfc2616#section-14.36
23
- referer: headers['HTTP_REFERER'],
24
- request_id: headers['action_dispatch.request_id'],
25
- remote_ip: headers['action_dispatch.remote_ip'],
26
- remote_addr: headers['REMOTE_ADDR'],
27
- x_forwarded_for: headers['HTTP_X_FORWARDED_FOR'],
28
- forwarded: headers['HTTP_FORWARDED'] # RFC 7239
29
- }
30
-
31
- # Some of these 'headers' include recursive structures
32
- # that cause SystemStackErrors in JSON serialization,
33
- # so we convert them all to strings
34
- extracted_headers.transform_values(&:to_s)
61
+ LOGGED_HEADERS.each_with_object({}) do |(key, header), values|
62
+ next unless (header_val = headers[header])
63
+
64
+ # Some of these 'headers' include recursive structures
65
+ # that cause SystemStackErrors in JSON serialization,
66
+ # so we convert them all to strings
67
+ values[key] = header_val.to_s
68
+ end
35
69
  end
36
70
  end
37
71
  end
@@ -7,7 +7,7 @@ module BerkeleyLibrary
7
7
  SUMMARY = 'Opinionated Ruby/Rails logging for UC Berkeley Library'.freeze
8
8
  DESCRIPTION = 'A gem providing shared logging code for UC Berkeley Library gems and Rails applications'.freeze
9
9
  LICENSE = 'MIT'.freeze
10
- VERSION = '0.2.3'.freeze
10
+ VERSION = '0.2.4'.freeze
11
11
  HOMEPAGE = 'https://github.com/BerkeleyLibrary/logging'.freeze
12
12
 
13
13
  private_class_method :new
@@ -34,6 +34,13 @@ module BerkeleyLibrary
34
34
  Configurator.configure(config)
35
35
  lograge = config.lograge
36
36
 
37
+ params = { authenticity_token: '8675309' }
38
+ request = OpenStruct.new(
39
+ origin: 'http://example.org:3000',
40
+ base_url: 'https://example.org:3443',
41
+ x_csrf_token: '5551212'
42
+ )
43
+
37
44
  request_headers = {
38
45
  'HTTP_REFERER' => 'value from HTTP_REFERER',
39
46
  'action_dispatch.request_id' => 'value from action_dispatch.request_id',
@@ -52,14 +59,25 @@ module BerkeleyLibrary
52
59
  forwarded: 'HTTP_FORWARDED'
53
60
  }
54
61
 
62
+ payload = {
63
+ params: params,
64
+ request: request,
65
+ headers: request_headers
66
+ }
67
+
55
68
  event = instance_double(ActiveSupport::Notifications::Event)
56
- allow(event).to receive(:payload).and_return({ headers: request_headers })
69
+ allow(event).to receive(:payload).and_return(payload)
57
70
 
58
71
  custom_options = lograge.custom_options
59
72
  data = custom_options.call(event)
60
73
  expect(data).to be_a(Hash)
61
- expect(data[:time]).to be_a(Time) # TODO: check for accuracy
74
+ expect(data[:time]).to be_a(Time)
75
+ expect(data[:time].to_i).to be_within(60).of(Time.now.to_i)
62
76
  expected_header_map.each { |xh, rh| expect(data[xh]).to eq(request_headers[rh]) }
77
+ expect(data[:authenticity_token]).to eq(params[:authenticity_token])
78
+ %i[origin base_url x_csrf_token].each do |attr|
79
+ expect(data[attr]).to eq(request.send(attr))
80
+ end
63
81
  end
64
82
 
65
83
  it 'formats Lograge data as a hash' do
@@ -127,7 +127,11 @@ module BerkeleyLibrary
127
127
  end
128
128
  end
129
129
 
130
- expect { Loggers.new_json_logger(out).error(ex_outer) }.not_to raise_error(SystemStackError)
130
+ begin
131
+ Loggers.new_json_logger(out).error(ex_outer)
132
+ rescue SystemStackError => e
133
+ RSpec::Expectations.fail_with("Expected no SystemStackError, but got #{e}: #{e.backtrace[0]}")
134
+ end
131
135
  end
132
136
  # rubocop:enable Naming/RescuedExceptionsVariableName
133
137
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkeley_library-logging
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Moles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-02 00:00:00.000000000 Z
11
+ date: 2021-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -290,6 +290,7 @@ files:
290
290
  - LICENSE.md
291
291
  - README.md
292
292
  - Rakefile
293
+ - artifacts/.keep
293
294
  - berkeley_library-logging.gemspec
294
295
  - docker-compose.yml
295
296
  - lib/berkeley_library/logging.rb