appydays 0.9.0 → 0.11.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/lib/appydays/loggable/sequel_logger.rb +2 -2
- data/lib/appydays/loggable/sidekiq_job_logger.rb +18 -4
- data/lib/appydays/loggable/spec_helpers.rb +1 -1
- data/lib/appydays/loggable.rb +73 -2
- data/lib/appydays/spec_helpers.rb +1 -1
- data/lib/appydays/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7233dee300e207e49803a368896ad6b098641db88b703d54860002055609826
|
4
|
+
data.tar.gz: 8c1d7694c1ab1695526676690900f1d5d12facee1adb4b3a823d409af22606a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b45d24f4ae6769ea2bd3b42b2985c404339d6b74238c33ae15d3413d8b04088137442dc4a62710b9ed8fdc215bc1bc98f2f91c14c6370550034e5a24a2b992f5
|
7
|
+
data.tar.gz: 27ac2dc1b1ee65373c807518df6a4cb0e2038b65f6ccababc20ba89a2b3cc3bd5a1042e06c838f69ebaa054f8c88ef6e4ce42e8e61a2be063aaad61a48989020
|
@@ -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:
|
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:
|
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, &
|
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, &
|
31
|
+
self.call_inner(start, &)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -43,11 +43,13 @@ class Appydays::Loggable::SidekiqJobLogger < Sidekiq::JobLogger
|
|
43
43
|
yield
|
44
44
|
duration = self.elapsed(start)
|
45
45
|
log_method = duration >= self.slow_job_seconds ? :warn : :info
|
46
|
-
self.logger.send(log_method, "job_done", duration: duration * 1000)
|
46
|
+
self.logger.send(log_method, "job_done", duration: duration * 1000, **self.class.job_tags)
|
47
47
|
rescue StandardError
|
48
48
|
# Do not log the error since it is probably a sidekiq retry error
|
49
|
-
self.logger.error("job_fail", duration: self.elapsed(start) * 1000)
|
49
|
+
self.logger.error("job_fail", duration: self.elapsed(start) * 1000, **self.class.job_tags)
|
50
50
|
raise
|
51
|
+
ensure
|
52
|
+
self.class.job_tags.clear
|
51
53
|
end
|
52
54
|
|
53
55
|
protected def elapsed(start)
|
@@ -58,6 +60,18 @@ class Appydays::Loggable::SidekiqJobLogger < Sidekiq::JobLogger
|
|
58
60
|
return ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
59
61
|
end
|
60
62
|
|
63
|
+
# Set job tags that get logged out in the "job_done" and "job_fail" messages.
|
64
|
+
# See README for more info.
|
65
|
+
# We do NOT merge the job_tags in with critical errors (death and job_error),
|
66
|
+
# since those will log the job args, and they aren't properly tested right now.
|
67
|
+
# We may add support in the future.
|
68
|
+
def self.set_job_tags(**tags)
|
69
|
+
Thread.current[:appydays_sidekiq_job_logger_job_tags] ||= {}
|
70
|
+
Thread.current[:appydays_sidekiq_job_logger_job_tags].merge!(tags)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.job_tags = Thread.current[:appydays_sidekiq_job_logger_job_tags] || {}
|
74
|
+
|
61
75
|
def self.error_handler(ex, ctx)
|
62
76
|
# ctx looks like:
|
63
77
|
# {
|
@@ -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
|
39
|
+
appender = SemanticLogger.add_appender(io:, level:)
|
40
40
|
appender.formatter = formatter if formatter
|
41
41
|
begin
|
42
42
|
yield
|
data/lib/appydays/loggable.rb
CHANGED
@@ -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, &
|
98
|
-
return SemanticLogger.named_tagged(tags, &
|
168
|
+
def with_log_tags(tags, &)
|
169
|
+
return SemanticLogger.named_tagged(tags, &)
|
99
170
|
end
|
100
171
|
end
|
101
172
|
end
|
data/lib/appydays/version.rb
CHANGED
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.
|
4
|
+
version: 0.11.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: 2024-
|
11
|
+
date: 2024-10-20 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:
|
284
|
+
version: 3.1.0
|
271
285
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
272
286
|
requirements:
|
273
287
|
- - ">="
|