appydays 0.8.0 → 0.10.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: cfd157bff00c9a41a678f4f8877660e90f9bb094b367ea0bedf153d7ea30d528
4
- data.tar.gz: 4da1794259b8f5a2ad0d43544092487b91b56f840439404567ca26467264c8d8
3
+ metadata.gz: d460b440b0d1e096ac8d1aa9d21da1b8de8b0147ae1698f65242a9d047db7f9b
4
+ data.tar.gz: bb73da0a0a8dac1afd63ff66ff25427736f79e2ac3e6f16757a8643b04385885
5
5
  SHA512:
6
- metadata.gz: 85e0c276cb7978298f3a14fadfa71e767b216b2fd419beecda09fe6855eea3de8cf58e9651869eae45a1317a47df659ff0db69de8daf29533040f190eaac07b2
7
- data.tar.gz: 0d07c35465caebd19c9cb86a3d2113cdd1bacebe80cfedd2251da076fdaadec46d0fa47c5e147e9c3fee78ec7b1afff39291ea30057b20e562c28010af4710dc
6
+ metadata.gz: 645fcf14b44cf77ac41ad813b61be5fd0ffb957ed920e068d5bc277372a4b6aba567ed4a86e3017fbfbc76dba1eb3d9315fb5ade7fe4a412cf7903dfbbe8aec7
7
+ data.tar.gz: 1b551951f4dca1bf41bebadbc0b2f49e84b7bd5a2e2797e8822e953e621624c95fd4db12605a3ae5093a99d7968416de928b94319147feda2bb785f4117ecdff
@@ -24,6 +24,13 @@ require "appydays/version"
24
24
  # it won't get used, because .env files don't stomp what is already in the environment
25
25
  # (we don't want to use `overload`).
26
26
  # So we have some trickery to overwrite only PORT.
27
+ #
28
+ # @param rack_env [nil,String] Value like 'development' or 'production' to use to load .env files.
29
+ # If not given, use +env['RACK_ENV']+ or +default_rack_env+.
30
+ # @param default_rack_env [String] If +env['RACK_ENV']+ is not set, use this value.
31
+ # @param env [Hash] Hash to read and mutate.
32
+ # Pass in a different hash to load environment variables into it instead of ENV.
33
+ # Useful for testing, or to get the config for another environment.
27
34
  module Appydays::Dotenviable
28
35
  def self.load(rack_env: nil, default_rack_env: "development", env: ENV)
29
36
  original_port = env.delete("PORT")
@@ -33,7 +40,17 @@ module Appydays::Dotenviable
33
40
  ".env.#{rack_env}",
34
41
  ".env",
35
42
  ]
43
+ orig_env = nil
44
+ if env.object_id != ENV.object_id
45
+ orig_env = ENV.to_h
46
+ ENV.replace(env)
47
+ end
36
48
  Dotenv.load(*paths)
49
+ if orig_env
50
+ env.merge!(ENV)
51
+ ENV.replace(orig_env)
52
+ end
53
+
37
54
  env["PORT"] ||= original_port
38
55
  env["RACK_ENV"] ||= rack_env
39
56
  end
@@ -45,7 +45,7 @@ class Sequel::Database
45
45
  :info,
46
46
  proc { args ? "#{message}; #{args.inspect}" : message },
47
47
  proc do
48
- o = {message: message}
48
+ o = {message:}
49
49
  o[:args] = args unless args.nil?
50
50
  ["sequel_log", o]
51
51
  end,
@@ -62,7 +62,7 @@ class Sequel::Database
62
62
  proc { "(#{'%0.6fs' % duration}) #{message}" },
63
63
  proc do
64
64
  query = AppydaysLogger.truncate_message(message)
65
- params = {duration: duration * 1000, query: query}
65
+ params = {duration: duration * 1000, query:}
66
66
  if query != message
67
67
  params[:truncated] = true
68
68
  was_truncated = true
@@ -20,7 +20,7 @@ class Appydays::Loggable::SidekiqJobLogger < Sidekiq::JobLogger
20
20
 
21
21
  Sidekiq.logger = self.logger
22
22
 
23
- def call(item, _queue, &block)
23
+ def call(item, _queue, &)
24
24
  start = self.now
25
25
  tags = {
26
26
  job_class: item["class"],
@@ -28,7 +28,7 @@ class Appydays::Loggable::SidekiqJobLogger < Sidekiq::JobLogger
28
28
  thread_id: self.tid,
29
29
  }
30
30
  self.with_log_tags(tags) do
31
- self.call_inner(start, &block)
31
+ self.call_inner(start, &)
32
32
  end
33
33
  end
34
34
 
@@ -36,7 +36,7 @@ module Appydays::Loggable::SpecHelpers
36
36
  loggers.each { |log| log.level = level }
37
37
 
38
38
  io = StringIO.new
39
- appender = SemanticLogger.add_appender(io: io, level: level)
39
+ appender = SemanticLogger.add_appender(io:, level:)
40
40
  appender.formatter = formatter if formatter
41
41
  begin
42
42
  yield
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "semantic_logger"
4
+ require "semantic_logger/formatters/raw"
5
+ require "semantic_logger/formatters/json"
4
6
 
5
7
  require "appydays/version"
6
8
 
@@ -29,6 +31,75 @@ class SemanticLogger::Formatters::Raw
29
31
  end
30
32
  end
31
33
 
34
+ # SemanticLogger Formatter that truncates large strings in the structured log payload.
35
+ # If the emitted JSON log is longer than +max_message_len+:
36
+ # - the payload is walked,
37
+ # - any strings with a length greater than +max_string_len+ are shortened using +shorten_string+.
38
+ # Override +shorten_string+ for custom behavior.
39
+ # - any key +:stack_trace+ has its array truncated. Stack traces are very large,
40
+ # but contain short strings. Override +truncate_stack_trace+ for custom behavior.
41
+ class SemanticLogger::Formatters::JsonTrunc < SemanticLogger::Formatters::Raw
42
+ attr_accessor :max_message_len, :max_string_len
43
+
44
+ def initialize(max_message_len: 1024 * 3, max_string_len: 300, **args)
45
+ super(**args)
46
+ @max_message_len = max_message_len
47
+ @max_string_len = max_string_len
48
+ end
49
+
50
+ def truncate_at(max_message_len, max_string_len)
51
+ @max_message_len = max_message_len
52
+ @max_string_len = max_string_len
53
+ end
54
+
55
+ def call(log, logger)
56
+ r = super
57
+ rj = r.to_json
58
+ return rj if rj.length <= @max_message_len
59
+ rshort = self.trim_long_strings(r)
60
+ return rshort.to_json
61
+ end
62
+
63
+ def trim_long_strings(v)
64
+ case v
65
+ when Hash
66
+ v.each_with_object({}) do |(hk, hv), memo|
67
+ memo[hk] =
68
+ if hk == :stack_trace && hv.is_a?(Array)
69
+ self.truncate_stack_trace(hv)
70
+ else
71
+ self.trim_long_strings(hv)
72
+ end
73
+ end
74
+ when Array
75
+ v.map { |item| self.trim_long_strings(item) }
76
+ when String
77
+ if v.size > @max_string_len
78
+ self.shorten_string(v)
79
+ else
80
+ v
81
+ end
82
+ else
83
+ v
84
+ end
85
+ end
86
+
87
+ # Given a long string, return the truncated string.
88
+ # @param v [String]
89
+ # @return [String]
90
+ def shorten_string(v)
91
+ return v[..@max_string_len] + "..."
92
+ end
93
+
94
+ # Given a stack trace array, return the array to log.
95
+ # @param arr [Array]
96
+ # @return [Array]
97
+ def truncate_stack_trace(arr)
98
+ return arr if arr.length <= 4
99
+ return [arr[0], arr[1], "skipped #{arr.length - 4} frames", arr[-2], arr[-1]]
100
+ end
101
+ end
102
+
32
103
  ##
33
104
  # Helpers for working with structured logging.
34
105
  # Use this instead of calling semantic_logger directly.
@@ -94,8 +165,8 @@ module Appydays::Loggable
94
165
  end
95
166
 
96
167
  module Methods
97
- def with_log_tags(tags, &block)
98
- return SemanticLogger.named_tagged(tags, &block)
168
+ def with_log_tags(tags, &)
169
+ return SemanticLogger.named_tagged(tags, &)
99
170
  end
100
171
  end
101
172
  end
@@ -85,7 +85,7 @@ module Appydays::SpecHelpers
85
85
  end
86
86
 
87
87
  protected def change_tz(t, zone)
88
- return t.change(zone: zone) if t.respond_to?(:change)
88
+ return t.change(zone:) if t.respond_to?(:change)
89
89
  prev_tz = ENV.fetch("TZ", nil)
90
90
  begin
91
91
  ENV["TZ"] = zone
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appydays
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydays
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lithic Tech
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-27 00:00:00.000000000 Z
11
+ date: 2024-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -220,6 +220,20 @@ dependencies:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
222
  version: '6.0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: simplecov
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.22'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.22'
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: webmock
225
239
  requirement: !ruby/object:Gem::Requirement
@@ -267,7 +281,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
267
281
  requirements:
268
282
  - - ">="
269
283
  - !ruby/object:Gem::Version
270
- version: 2.7.0
284
+ version: 3.1.0
271
285
  required_rubygems_version: !ruby/object:Gem::Requirement
272
286
  requirements:
273
287
  - - ">="