hubbado-log 1.2.0 → 1.3.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/ChangeLog.md +42 -0
- data/README.md +62 -3
- data/hubbado-log.gemspec +1 -1
- data/lib/hubbado/log/configuration.rb +10 -2
- data/lib/hubbado/log/controls/log_handler.rb +55 -10
- data/lib/hubbado/log/log.rb +10 -6
- data/lib/hubbado/log/logger.rb +23 -5
- data/lib/hubbado/log/tags.rb +82 -0
- data/lib/hubbado/log.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49c303fe323be43f901ed8ef3958b87c79296af3a15efb11c9efb8a9b57156aa
|
|
4
|
+
data.tar.gz: 97bc2f947b3a4fc0cfd1845c34d722d6608cf36c1daf853334d3b3b03c4171b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fde7c3bf0995e34348f47a8441df1b95cf9505c909b08bac8fcc409f994ce8c8eb28cb05343e24b4066977a804434ced09cad3fb36e75908e375d3bddbc81304
|
|
7
|
+
data.tar.gz: 4f4cae84446c3d1bdf8a9ebb2b986f82a558c623af90a3278c62fa67ee8a23a55163129efc787758b5434faf101346e15187c9f112007333b7295cb26cf3648f
|
data/ChangeLog.md
CHANGED
|
@@ -4,6 +4,48 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
# [1.3.0 - 2026-08-15]
|
|
8
|
+
## Added
|
|
9
|
+
- Tags, a second filtering axis beside the level. A message names its concern
|
|
10
|
+
with `tag:` or `tags:`, and `LOG_TAGS` decides which tagged messages are
|
|
11
|
+
written. The syntax and semantics are Eventide's log gem's, so a string an
|
|
12
|
+
operator writes means the same thing in both codebases.
|
|
13
|
+
- `config.tags`, set in code the way `config.level` is, and a `tags:` keyword on
|
|
14
|
+
`Logger.new` so one logger can name its own list without the process being
|
|
15
|
+
turned up around it — the escape hatch the level already had.
|
|
16
|
+
- `Controls::LogHandler` records every message it is given in `messages`, answers
|
|
17
|
+
`logged?` with or without a severity, resets with `reset`, and builds a wired
|
|
18
|
+
logger with `.attach` or `.logger`. Five downstream projects had each
|
|
19
|
+
hand-rolled the same thing because the control kept only the most recent; they
|
|
20
|
+
can delete their copy whenever it suits them. The attributes still read the
|
|
21
|
+
most recent, derived from `messages` rather than assigned beside it.
|
|
22
|
+
- `.attach` and `.logger` name `_all` as well as `trace`, so neither the
|
|
23
|
+
configured level nor the configured tag list decides what a spec can read back.
|
|
24
|
+
`.attach` raises a named `ArgumentError` for a class carrying no logger rather
|
|
25
|
+
than failing on nil.
|
|
26
|
+
|
|
27
|
+
## Changed
|
|
28
|
+
- The test suite sets `LOG_TAGS` rather than defaulting it, so a value left in a
|
|
29
|
+
developer's shell cannot decide which tests can write anything.
|
|
30
|
+
|
|
31
|
+
## Compatibility
|
|
32
|
+
Nothing that exists breaks. A handler's arguments are unchanged — tags decide
|
|
33
|
+
whether it is called, and are not passed to it. Every handler across the
|
|
34
|
+
consuming repositories was checked and needs no edit.
|
|
35
|
+
|
|
36
|
+
One theoretical change: the severity methods and `Hubbado::Log.log` now name
|
|
37
|
+
`tag:` and `tags:`, so a call site passing its data as bare keywords —
|
|
38
|
+
`logger.info('x', record_id: 7)`, which worked because Ruby folded them into a
|
|
39
|
+
positional hash while the methods accepted none — raises instead. No such call
|
|
40
|
+
site exists in any consuming repository; pass the hash explicitly if one appears.
|
|
41
|
+
|
|
42
|
+
## Not included
|
|
43
|
+
A tag declared once per component, and tags reaching a log handler. Neither has
|
|
44
|
+
an implementer: nothing tags a message yet, and no handler prints or routes on
|
|
45
|
+
one. Eventide does not pass tags to its own output either — they filter, and
|
|
46
|
+
stop there. Both are worth adding when something needs them, and neither has to
|
|
47
|
+
break a handler to arrive.
|
|
48
|
+
|
|
7
49
|
# [1.2.0 - 2026-08-14]
|
|
8
50
|
## Added
|
|
9
51
|
- A `trace` level, below `debug`. Program flow — a line per iteration of a loop —
|
data/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Or install it yourself as:
|
|
|
20
20
|
|
|
21
21
|
## Level
|
|
22
22
|
|
|
23
|
-
A
|
|
23
|
+
A message below the level reaches no handler.
|
|
24
24
|
|
|
25
25
|
```ruby
|
|
26
26
|
Hubbado::Log.configuration do |config|
|
|
@@ -45,13 +45,72 @@ Levels, lowest first:
|
|
|
45
45
|
| `warn` | Unexpected state that is not an error, or is recoverable, and that a developer or operator should examine |
|
|
46
46
|
| `error` | Message logged just prior to raising an error |
|
|
47
47
|
| `fatal` | Message recorded, when possible, as the process is terminating due to an error |
|
|
48
|
-
|
|
49
|
-
name its own with
|
|
48
|
+
|
|
49
|
+
A single logger can name its own with
|
|
50
|
+
`Hubbado::Log::Logger.new(subject, handlers, level: :debug)`.
|
|
50
51
|
|
|
51
52
|
`LOG_LEVEL` is shared with Eventide's log gem, which writes names this gem does not
|
|
52
53
|
know. A name that is not one of `debug`, `info`, `warn`, `error`, `fatal` or
|
|
53
54
|
`unknown` leaves the level at `info` rather than raising.
|
|
54
55
|
|
|
56
|
+
## Tags
|
|
57
|
+
|
|
58
|
+
A level says what kind of thing happened. A tag says which concern it belongs to, so a
|
|
59
|
+
completion that is simply frequent can be filtered out without being demoted to `debug`.
|
|
60
|
+
|
|
61
|
+
Name the concern where the message is written. `tag:` and `tags:` are both accepted, and a
|
|
62
|
+
message can use either or both:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
logger.info('Invoice raised', tags: [:invoicing, :billing])
|
|
66
|
+
logger.trace('Row read', tag: :data)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `LOG_TAGS`
|
|
70
|
+
|
|
71
|
+
Which tagged messages are written is decided by `LOG_TAGS`, a comma-separated list:
|
|
72
|
+
|
|
73
|
+
$ LOG_TAGS='_untagged,-data,billing,invoicing' ./my-command
|
|
74
|
+
|
|
75
|
+
| Entry | Meaning |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `name` | Write messages carrying this tag |
|
|
78
|
+
| `-name` | Do not write messages carrying this tag, even if another entry includes them |
|
|
79
|
+
| `_untagged` | Write messages carrying no tag at all |
|
|
80
|
+
| `_all` | Write every message, whatever it carries |
|
|
81
|
+
|
|
82
|
+
A message can also tag itself `:*`, which writes it whatever the list says.
|
|
83
|
+
|
|
84
|
+
**Write the list with no spaces.** It is split on commas and nothing else, so `http, cache`
|
|
85
|
+
asks for a tag named `http` and another named `⎵cache`, which nothing carries. This is
|
|
86
|
+
Eventide's behaviour, kept deliberately so one `LOG_TAGS` means the same thing to both gems.
|
|
87
|
+
|
|
88
|
+
Tags compose with the level rather than replacing it: both filters have to pass, so a tag
|
|
89
|
+
cannot raise a message above the level and the level cannot rescue one the list leaves out.
|
|
90
|
+
|
|
91
|
+
A single logger can name its own list, as it can name its own level, so one component can be
|
|
92
|
+
read without turning up everything around it:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
Hubbado::Log::Logger.new(subject, handlers, level: :trace, tags: '_all')
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The syntax and its behaviour are Eventide's log gem, copied deliberately so that a string an
|
|
99
|
+
operator writes means the same thing in both codebases. Two consequences of that are worth
|
|
100
|
+
knowing before adopting tags:
|
|
101
|
+
|
|
102
|
+
- **`LOG_TAGS` is an allow-list.** A tagged message is written only if the list names it. Adding
|
|
103
|
+
a tag to a call site therefore *silences* that message everywhere `LOG_TAGS` has not been
|
|
104
|
+
updated — cron, CI and production included. Ship the variable with the tag.
|
|
105
|
+
- **There is no way to mute one concern and keep the rest.** `-name` subtracts only from
|
|
106
|
+
messages an include has already matched, and `_all` is answered before any exclusion, so
|
|
107
|
+
`_all,-data` still writes `data` messages. Keeping everything except one concern means naming
|
|
108
|
+
the others.
|
|
109
|
+
|
|
110
|
+
`LOG_TAGS` is shared with Eventide's log gem, as `LOG_LEVEL` is. In a process running both, one
|
|
111
|
+
list decides for both, and an application whose messages are all untagged goes silent unless the
|
|
112
|
+
list contains `_untagged`.
|
|
113
|
+
|
|
55
114
|
## Development
|
|
56
115
|
|
|
57
116
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/hubbado-log.gemspec
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
module Hubbado
|
|
2
2
|
class Log
|
|
3
3
|
class Configuration
|
|
4
|
-
# Tracing is off until somebody asks for it, which is what lets a debug
|
|
4
|
+
# Tracing is off until somebody asks for it, which is what lets a debug message be written
|
|
5
5
|
# for a human watching one run without it also reaching every unattended log.
|
|
6
6
|
DEFAULT_LEVEL = :info
|
|
7
7
|
|
|
8
8
|
attr_accessor :loggers
|
|
9
9
|
attr_reader :level
|
|
10
|
+
attr_reader :tags
|
|
10
11
|
|
|
11
|
-
def initialize(level: nil)
|
|
12
|
+
def initialize(level: nil, tags: nil)
|
|
12
13
|
@loggers = []
|
|
13
14
|
self.level = level || DEFAULT_LEVEL
|
|
15
|
+
self.tags = tags
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Takes the LOG_TAGS string as readily as a list, so nothing upstream has to know the
|
|
19
|
+
# syntax in order to hand a value in.
|
|
20
|
+
def tags=(value)
|
|
21
|
+
@tags = Tags.parse(value)
|
|
14
22
|
end
|
|
15
23
|
|
|
16
24
|
# A name rather than a severity is answered with the default instead of an exception.
|
|
@@ -2,18 +2,63 @@ module Hubbado
|
|
|
2
2
|
class Log
|
|
3
3
|
module Controls
|
|
4
4
|
class LogHandler < Hubbado::Log::LogHandler
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
# Everything a class logged, in order, because a run that reports two failures needs
|
|
6
|
+
# both of them. The attributes below read the most recent.
|
|
7
|
+
def messages
|
|
8
|
+
@messages ||= []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Replaces a class's logger with one writing here, keeping its subject. Neither the
|
|
12
|
+
# configured level nor the configured tags decide what a spec attaching one of these can
|
|
13
|
+
# read: it is asking what the class said, and the process's filters are not its subject.
|
|
14
|
+
def self.attach(instance, level: :trace, tags: Tags::ALL)
|
|
15
|
+
logger = instance.logger
|
|
16
|
+
|
|
17
|
+
if logger.nil?
|
|
18
|
+
raise ArgumentError, "#{instance.class} carries no logger to attach to. " \
|
|
19
|
+
"Use .logger for a class that is handed one instead."
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
new.tap do |handler|
|
|
23
|
+
instance.logger = Logger.new(logger.subject, [handler], level: level, tags: tags)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# For a class handed a logger rather than carrying one, and for a spec that wants both.
|
|
28
|
+
def self.logger(subject = Subject.example, level: :trace, tags: Tags::ALL)
|
|
29
|
+
handler = new
|
|
30
|
+
|
|
31
|
+
[handler, Logger.new(subject, [handler], level: level, tags: tags)]
|
|
32
|
+
end
|
|
10
33
|
|
|
11
34
|
def log(subject, severity, message, data = nil, stacktrace = nil)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
35
|
+
messages << {
|
|
36
|
+
subject: subject,
|
|
37
|
+
severity: severity,
|
|
38
|
+
message: message,
|
|
39
|
+
data: data,
|
|
40
|
+
stacktrace: stacktrace
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Named without a severity, this answers whether anything was written at all — which a
|
|
45
|
+
# spec would otherwise have to infer from an attribute never having been set. A severity
|
|
46
|
+
# is compared as a symbol, because #log takes a String as readily and passes on what it
|
|
47
|
+
# was given.
|
|
48
|
+
def logged?(severity = nil)
|
|
49
|
+
return !messages.empty? if severity.nil?
|
|
50
|
+
|
|
51
|
+
messages.any? { |written| written.fetch(:severity).to_s.to_sym == severity.to_s.to_sym }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def reset
|
|
55
|
+
@messages = []
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The most recent message. Derived rather than assigned alongside `messages`, so the two
|
|
59
|
+
# cannot disagree about which message is the latest.
|
|
60
|
+
%i[subject severity message data stacktrace].each do |field|
|
|
61
|
+
define_method(field) { messages.last&.fetch(field) }
|
|
17
62
|
end
|
|
18
63
|
end
|
|
19
64
|
end
|
data/lib/hubbado/log/log.rb
CHANGED
|
@@ -2,17 +2,18 @@ module Hubbado
|
|
|
2
2
|
class Log
|
|
3
3
|
include Dependency
|
|
4
4
|
|
|
5
|
-
# Ordered, because the level compares against them. `trace` is program flow, a
|
|
5
|
+
# Ordered, because the level compares against them. `trace` is program flow, a message per
|
|
6
6
|
# iteration; `debug` is the completion of a secondary operation, or a detail worth keeping;
|
|
7
7
|
# `info` is the completion of the principal operation of a class or utility.
|
|
8
8
|
SEVERITIES = { trace: 0, debug: 1, info: 2, warn: 3, error: 4, fatal: 5, unknown: 6 }.freeze
|
|
9
9
|
STACKTRACE_SEVERITIES = %i[warn error fatal unknown].freeze
|
|
10
10
|
|
|
11
11
|
LEVEL_VARIABLE = "LOG_LEVEL".freeze
|
|
12
|
+
TAGS_VARIABLE = "LOG_TAGS".freeze
|
|
12
13
|
|
|
13
|
-
# The one place the environment is read. A command names its level here or not at
|
|
14
|
-
# and everything downstream is handed the value rather than the variable.
|
|
15
|
-
@config = Configuration.new(level: ENV[LEVEL_VARIABLE])
|
|
14
|
+
# The one place the environment is read. A command names its level and tags here or not at
|
|
15
|
+
# all, and everything downstream is handed the value rather than the variable.
|
|
16
|
+
@config = Configuration.new(level: ENV[LEVEL_VARIABLE], tags: ENV[TAGS_VARIABLE])
|
|
16
17
|
|
|
17
18
|
class << self
|
|
18
19
|
attr_reader :config
|
|
@@ -31,8 +32,11 @@ module Hubbado
|
|
|
31
32
|
@logger = Logger.new('', loggers)
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
# The keywords are named rather than swept up with the positionals: a method taking only
|
|
36
|
+
# `*args` accepts no keywords, so Ruby would fold them into a trailing hash and they would
|
|
37
|
+
# arrive as the message's data — which a handler hands to Rollbar as the exception.
|
|
38
|
+
def log(*args, tag: nil, tags: nil)
|
|
39
|
+
logger.log(*args, tag: tag, tags: tags)
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
42
|
|
data/lib/hubbado/log/logger.rb
CHANGED
|
@@ -4,18 +4,23 @@ module Hubbado
|
|
|
4
4
|
attr_accessor :log_handlers
|
|
5
5
|
attr_accessor :subject
|
|
6
6
|
|
|
7
|
-
def initialize(subject, log_handlers = [], level: nil)
|
|
7
|
+
def initialize(subject, log_handlers = [], level: nil, tags: nil)
|
|
8
8
|
self.subject = subject
|
|
9
9
|
self.log_handlers = Array(log_handlers)
|
|
10
10
|
@level = level
|
|
11
|
+
@tags = tags
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
# A logger built without one follows the configuration, which is every logger the gem
|
|
14
|
-
# builds itself: `Log.configure` names
|
|
15
|
+
# builds itself: `Log.configure` names neither, so a class using the Dependency module
|
|
15
16
|
# takes whatever the process was configured for.
|
|
16
17
|
def level = @level || Log.config.level
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
# Named per logger as well as per process, as the level is and as Eventide's log gem has
|
|
20
|
+
# it, so one component can be read without turning up everything around it.
|
|
21
|
+
def tags = @tags.nil? ? Log.config.tags : Tags.parse(@tags)
|
|
22
|
+
|
|
23
|
+
def log(severity, msg, data = nil, tag: nil, tags: nil)
|
|
19
24
|
unless SEVERITIES.keys.include? severity.to_sym
|
|
20
25
|
raise ArgumentError, "Unknown serverity #{severity}"
|
|
21
26
|
end
|
|
@@ -24,6 +29,19 @@ module Hubbado
|
|
|
24
29
|
# not what may be said, so quietening a logger must not turn a typo into silence.
|
|
25
30
|
return if SEVERITIES.fetch(severity.to_sym) < SEVERITIES.fetch(level)
|
|
26
31
|
|
|
32
|
+
# Singular and plural are both accepted and both kept, following Eventide's log gem,
|
|
33
|
+
# where real call sites use either and occasionally hand an array to the singular one.
|
|
34
|
+
#
|
|
35
|
+
# Named as symbols, because that is what LOG_TAGS is parsed into: a String here would
|
|
36
|
+
# match nothing and its message would go missing with nothing said about it.
|
|
37
|
+
message_tags = (Array(tags) + Array(tag)).map { |name| name.to_s.to_sym }
|
|
38
|
+
|
|
39
|
+
# Both filters have to pass. A tag cannot raise a message above the level, and the level
|
|
40
|
+
# cannot rescue one the list leaves out.
|
|
41
|
+
#
|
|
42
|
+
# `self.` because the `tags:` keyword above shadows the reader.
|
|
43
|
+
return unless self.tags.write?(message_tags)
|
|
44
|
+
|
|
27
45
|
stacktrace = if data.is_a?(Exception)
|
|
28
46
|
data.full_message
|
|
29
47
|
elsif STACKTRACE_SEVERITIES.include?(severity)
|
|
@@ -36,8 +54,8 @@ module Hubbado
|
|
|
36
54
|
end
|
|
37
55
|
|
|
38
56
|
SEVERITIES.each_key do |severity|
|
|
39
|
-
define_method severity do |msg, data = nil|
|
|
40
|
-
log severity, msg, data
|
|
57
|
+
define_method severity do |msg, data = nil, tag: nil, tags: nil|
|
|
58
|
+
log severity, msg, data, tag: tag, tags: tags
|
|
41
59
|
end
|
|
42
60
|
end
|
|
43
61
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module Hubbado
|
|
2
|
+
class Log
|
|
3
|
+
# The operator's list, from LOG_TAGS: an allow-list a message's own tags have to intersect
|
|
4
|
+
# before it is written.
|
|
5
|
+
class Tags
|
|
6
|
+
# Every tag is written, whatever else the list says.
|
|
7
|
+
ALL = :_all
|
|
8
|
+
|
|
9
|
+
# Messages carrying no tag at all are written. Without it, naming any tag silences them.
|
|
10
|
+
UNTAGGED = :_untagged
|
|
11
|
+
|
|
12
|
+
# A message marks itself as written whatever the operator asked for.
|
|
13
|
+
EVERY_MESSAGE = :*
|
|
14
|
+
|
|
15
|
+
EXCLUSION = "-".freeze
|
|
16
|
+
|
|
17
|
+
# Split on commas and nothing else, which is all Eventide's log gem does. Trimming the
|
|
18
|
+
# spaces would be kinder, and would make one LOG_TAGS mean different things in the two gems
|
|
19
|
+
# that share the variable — the divergence this gem cannot afford.
|
|
20
|
+
def self.parse(value)
|
|
21
|
+
return value if value.is_a?(self)
|
|
22
|
+
return new if value.nil?
|
|
23
|
+
return new(value) if value.is_a?(Array)
|
|
24
|
+
|
|
25
|
+
new(value.to_s.split(","))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
attr_reader :tags
|
|
29
|
+
|
|
30
|
+
def initialize(tags = [])
|
|
31
|
+
@tags = Array(tags).map { |tag| tag.to_s.to_sym }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# An exclusion-only list still counts as the operator having named tags, which is what
|
|
35
|
+
# makes `-data` on its own silence everything rather than subtract from everything.
|
|
36
|
+
def any?
|
|
37
|
+
!tags.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Branch for branch from Eventide's log gem, so that a string an operator writes means the
|
|
41
|
+
# same thing in both codebases. That includes the awkward part: `_all` is answered before
|
|
42
|
+
# any exclusion, so `_all,-data` writes `data` messages regardless.
|
|
43
|
+
def write?(message_tags)
|
|
44
|
+
message_tags = Array(message_tags)
|
|
45
|
+
|
|
46
|
+
return true if message_tags.empty? && !any?
|
|
47
|
+
return true if message_tags.include?(EVERY_MESSAGE)
|
|
48
|
+
return true if named?(ALL)
|
|
49
|
+
return true if message_tags.empty? && named?(UNTAGGED)
|
|
50
|
+
return true if !message_tags.empty? && any? && intersect?(message_tags)
|
|
51
|
+
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def named?(tag)
|
|
58
|
+
tags.include?(tag)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def intersect?(message_tags)
|
|
62
|
+
return false if message_tags.intersect?(excluded)
|
|
63
|
+
|
|
64
|
+
included.intersect?(message_tags)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def included
|
|
68
|
+
@included ||= tags.reject { |tag| excluded?(tag) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def excluded
|
|
72
|
+
@excluded ||= tags
|
|
73
|
+
.select { |tag| excluded?(tag) }
|
|
74
|
+
.map { |tag| tag.to_s.delete_prefix(EXCLUSION).to_sym }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def excluded?(tag)
|
|
78
|
+
tag.to_s.start_with?(EXCLUSION)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
data/lib/hubbado/log.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hubbado-log
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hubbado Devs
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- lib/hubbado/log/log.rb
|
|
87
87
|
- lib/hubbado/log/log_handler.rb
|
|
88
88
|
- lib/hubbado/log/logger.rb
|
|
89
|
+
- lib/hubbado/log/tags.rb
|
|
89
90
|
homepage: https://www.github.com/hubbado/hubbado-log
|
|
90
91
|
licenses:
|
|
91
92
|
- MIT
|