logster 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +19 -19
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +16 -16
  5. data/CHANGELOG.md +172 -169
  6. data/Gemfile +4 -4
  7. data/Guardfile +8 -8
  8. data/LICENSE.txt +22 -22
  9. data/README.md +99 -99
  10. data/Rakefile +21 -21
  11. data/assets/fonts/FontAwesome.otf +0 -0
  12. data/assets/fonts/fontawesome-webfont.eot +0 -0
  13. data/assets/fonts/fontawesome-webfont.svg +639 -639
  14. data/assets/fonts/fontawesome-webfont.ttf +0 -0
  15. data/assets/fonts/fontawesome-webfont.woff +0 -0
  16. data/assets/fonts/fontawesome-webfont.woff2 +0 -0
  17. data/assets/images/Icon-144_rounded.png +0 -0
  18. data/assets/images/Icon-144_square.png +0 -0
  19. data/assets/images/icon_144x144.png +0 -0
  20. data/assets/images/icon_64x64.png +0 -0
  21. data/assets/javascript/client-app.js +106 -100
  22. data/assets/stylesheets/client-app.css +1 -1
  23. data/build_client_app.sh +0 -0
  24. data/client-app/.editorconfig +20 -20
  25. data/client-app/.ember-cli +9 -9
  26. data/client-app/.eslintignore +19 -19
  27. data/client-app/.eslintrc.js +46 -46
  28. data/client-app/.gitignore +23 -23
  29. data/client-app/.travis.yml +27 -27
  30. data/client-app/.watchmanconfig +3 -3
  31. data/client-app/README.md +57 -57
  32. data/client-app/app/app.js +0 -0
  33. data/client-app/app/components/actions-menu.js +43 -37
  34. data/client-app/app/components/env-tab.js +80 -44
  35. data/client-app/app/components/message-info.js +0 -0
  36. data/client-app/app/components/message-row.js +0 -0
  37. data/client-app/app/components/panel-resizer.js +0 -0
  38. data/client-app/app/components/tab-contents.js +27 -27
  39. data/client-app/app/components/tabbed-section.js +0 -0
  40. data/client-app/app/components/time-formatter.js +0 -0
  41. data/client-app/app/components/update-time.js +0 -0
  42. data/client-app/app/controllers/index.js +0 -0
  43. data/client-app/app/controllers/show.js +0 -0
  44. data/client-app/app/index.html +29 -29
  45. data/client-app/app/initializers/app-init.js +67 -72
  46. data/client-app/app/lib/preload.js +20 -14
  47. data/client-app/app/lib/utilities.js +149 -140
  48. data/client-app/app/models/message-collection.js +0 -0
  49. data/client-app/app/models/message.js +100 -100
  50. data/client-app/app/resolver.js +0 -0
  51. data/client-app/app/router.js +0 -0
  52. data/client-app/app/routes/index.js +0 -0
  53. data/client-app/app/routes/show.js +0 -0
  54. data/client-app/app/styles/app.css +527 -521
  55. data/client-app/app/templates/application.hbs +2 -2
  56. data/client-app/app/templates/components/actions-menu.hbs +12 -12
  57. data/client-app/app/templates/components/env-tab.hbs +10 -10
  58. data/client-app/app/templates/components/message-info.hbs +41 -41
  59. data/client-app/app/templates/components/message-row.hbs +15 -15
  60. data/client-app/app/templates/components/panel-resizer.hbs +3 -3
  61. data/client-app/app/templates/components/tabbed-section.hbs +10 -10
  62. data/client-app/app/templates/components/time-formatter.hbs +1 -1
  63. data/client-app/app/templates/index.hbs +58 -58
  64. data/client-app/app/templates/show.hbs +7 -7
  65. data/client-app/config/environment.js +51 -51
  66. data/client-app/config/optional-features.json +3 -3
  67. data/client-app/config/targets.js +18 -18
  68. data/client-app/ember-cli-build.js +29 -29
  69. data/client-app/package-lock.json +11365 -11365
  70. data/client-app/package.json +56 -56
  71. data/client-app/testem.js +25 -25
  72. data/client-app/tests/index.html +34 -34
  73. data/client-app/tests/integration/components/env-tab-test.js +123 -73
  74. data/client-app/tests/integration/components/message-info-test.js +111 -26
  75. data/client-app/tests/test-helper.js +8 -8
  76. data/client-app/tests/unit/controllers/index-test.js +12 -12
  77. data/client-app/tests/unit/controllers/show-test.js +12 -12
  78. data/client-app/tests/unit/initializers/app-init-test.js +31 -31
  79. data/client-app/tests/unit/routes/index-test.js +11 -11
  80. data/client-app/tests/unit/routes/show-test.js +11 -11
  81. data/lib/examples/sidekiq_logster_reporter.rb +21 -21
  82. data/lib/logster.rb +54 -54
  83. data/lib/logster/base_store.rb +141 -141
  84. data/lib/logster/configuration.rb +26 -25
  85. data/lib/logster/defer_logger.rb +14 -14
  86. data/lib/logster/ignore_pattern.rb +65 -65
  87. data/lib/logster/logger.rb +113 -113
  88. data/lib/logster/message.rb +212 -212
  89. data/lib/logster/middleware/debug_exceptions.rb +26 -26
  90. data/lib/logster/middleware/reporter.rb +55 -55
  91. data/lib/logster/middleware/viewer.rb +222 -221
  92. data/lib/logster/rails/railtie.rb +63 -63
  93. data/lib/logster/redis_store.rb +566 -566
  94. data/lib/logster/scheduler.rb +54 -54
  95. data/lib/logster/version.rb +3 -3
  96. data/lib/logster/web.rb +14 -14
  97. data/logster.gemspec +35 -35
  98. data/test/examples/test_sidekiq_reporter_example.rb +46 -46
  99. data/test/fake_data/Gemfile +4 -4
  100. data/test/fake_data/generate.rb +10 -10
  101. data/test/logster/middleware/test_reporter.rb +19 -19
  102. data/test/logster/middleware/test_viewer.rb +96 -96
  103. data/test/logster/test_base_store.rb +147 -147
  104. data/test/logster/test_defer_logger.rb +34 -34
  105. data/test/logster/test_ignore_pattern.rb +41 -41
  106. data/test/logster/test_logger.rb +86 -86
  107. data/test/logster/test_message.rb +119 -119
  108. data/test/logster/test_redis_rate_limiter.rb +230 -230
  109. data/test/logster/test_redis_store.rb +720 -720
  110. data/test/test_helper.rb +38 -38
  111. data/vendor/assets/javascripts/logster.js.erb +39 -39
  112. metadata +1 -10
  113. data/client-app/app/components/tab-link.js +0 -5
  114. data/client-app/tests/integration/components/actions-menu-test.js +0 -26
  115. data/client-app/tests/integration/components/message-row-test.js +0 -26
  116. data/client-app/tests/integration/components/panel-resizer-test.js +0 -26
  117. data/client-app/tests/integration/components/tab-contents-test.js +0 -26
  118. data/client-app/tests/integration/components/tab-link-test.js +0 -26
  119. data/client-app/tests/integration/components/tabbed-section-test.js +0 -26
  120. data/client-app/tests/integration/components/time-formatter-test.js +0 -26
  121. data/client-app/tests/integration/components/update-time-test.js +0 -26
@@ -1,8 +1,8 @@
1
- import Application from '../app';
2
- import config from '../config/environment';
3
- import { setApplication } from '@ember/test-helpers';
4
- import { start } from 'ember-qunit';
5
-
6
- setApplication(Application.create(config.APP));
7
-
8
- start();
1
+ import Application from '../app';
2
+ import config from '../config/environment';
3
+ import { setApplication } from '@ember/test-helpers';
4
+ import { start } from 'ember-qunit';
5
+
6
+ setApplication(Application.create(config.APP));
7
+
8
+ start();
@@ -1,12 +1,12 @@
1
- import { module, test } from 'qunit';
2
- import { setupTest } from 'ember-qunit';
3
-
4
- module('Unit | Controller | index', function(hooks) {
5
- setupTest(hooks);
6
-
7
- // Replace this with your real tests.
8
- test('it exists', function(assert) {
9
- let controller = this.owner.lookup('controller:index');
10
- assert.ok(controller);
11
- });
12
- });
1
+ import { module, test } from 'qunit';
2
+ import { setupTest } from 'ember-qunit';
3
+
4
+ module('Unit | Controller | index', function(hooks) {
5
+ setupTest(hooks);
6
+
7
+ // Replace this with your real tests.
8
+ test('it exists', function(assert) {
9
+ let controller = this.owner.lookup('controller:index');
10
+ assert.ok(controller);
11
+ });
12
+ });
@@ -1,12 +1,12 @@
1
- import { module, test } from 'qunit';
2
- import { setupTest } from 'ember-qunit';
3
-
4
- module('Unit | Controller | show', function(hooks) {
5
- setupTest(hooks);
6
-
7
- // Replace this with your real tests.
8
- test('it exists', function(assert) {
9
- let controller = this.owner.lookup('controller:show');
10
- assert.ok(controller);
11
- });
12
- });
1
+ import { module, test } from 'qunit';
2
+ import { setupTest } from 'ember-qunit';
3
+
4
+ module('Unit | Controller | show', function(hooks) {
5
+ setupTest(hooks);
6
+
7
+ // Replace this with your real tests.
8
+ test('it exists', function(assert) {
9
+ let controller = this.owner.lookup('controller:show');
10
+ assert.ok(controller);
11
+ });
12
+ });
@@ -1,31 +1,31 @@
1
- import Application from '@ember/application';
2
-
3
- import { initialize } from 'client-app/initializers/app-init';
4
- import { module, test } from 'qunit';
5
- import { setupTest } from 'ember-qunit';
6
- import { run } from '@ember/runloop';
7
-
8
- module('Unit | Initializer | app-init', function(hooks) {
9
- setupTest(hooks);
10
-
11
- hooks.beforeEach(function() {
12
- this.TestApplication = Application.extend();
13
- this.TestApplication.initializer({
14
- name: 'initializer under test',
15
- initialize
16
- });
17
-
18
- this.application = this.TestApplication.create({ autoboot: false });
19
- });
20
-
21
- hooks.afterEach(function() {
22
- run(this.application, 'destroy');
23
- });
24
-
25
- // Replace this with your real tests.
26
- test('it works', async function(assert) {
27
- await this.application.boot();
28
-
29
- assert.ok(true);
30
- });
31
- });
1
+ import Application from '@ember/application';
2
+
3
+ import { initialize } from 'client-app/initializers/app-init';
4
+ import { module, test } from 'qunit';
5
+ import { setupTest } from 'ember-qunit';
6
+ import { run } from '@ember/runloop';
7
+
8
+ module('Unit | Initializer | app-init', function(hooks) {
9
+ setupTest(hooks);
10
+
11
+ hooks.beforeEach(function() {
12
+ this.TestApplication = Application.extend();
13
+ this.TestApplication.initializer({
14
+ name: 'initializer under test',
15
+ initialize
16
+ });
17
+
18
+ this.application = this.TestApplication.create({ autoboot: false });
19
+ });
20
+
21
+ hooks.afterEach(function() {
22
+ run(this.application, 'destroy');
23
+ });
24
+
25
+ // Replace this with your real tests.
26
+ test('it works', async function(assert) {
27
+ await this.application.boot();
28
+
29
+ assert.ok(true);
30
+ });
31
+ });
@@ -1,11 +1,11 @@
1
- import { module, test } from 'qunit';
2
- import { setupTest } from 'ember-qunit';
3
-
4
- module('Unit | Route | index', function(hooks) {
5
- setupTest(hooks);
6
-
7
- test('it exists', function(assert) {
8
- let route = this.owner.lookup('route:index');
9
- assert.ok(route);
10
- });
11
- });
1
+ import { module, test } from 'qunit';
2
+ import { setupTest } from 'ember-qunit';
3
+
4
+ module('Unit | Route | index', function(hooks) {
5
+ setupTest(hooks);
6
+
7
+ test('it exists', function(assert) {
8
+ let route = this.owner.lookup('route:index');
9
+ assert.ok(route);
10
+ });
11
+ });
@@ -1,11 +1,11 @@
1
- import { module, test } from 'qunit';
2
- import { setupTest } from 'ember-qunit';
3
-
4
- module('Unit | Route | show', function(hooks) {
5
- setupTest(hooks);
6
-
7
- test('it exists', function(assert) {
8
- let route = this.owner.lookup('route:show');
9
- assert.ok(route);
10
- });
11
- });
1
+ import { module, test } from 'qunit';
2
+ import { setupTest } from 'ember-qunit';
3
+
4
+ module('Unit | Route | show', function(hooks) {
5
+ setupTest(hooks);
6
+
7
+ test('it exists', function(assert) {
8
+ let route = this.owner.lookup('route:show');
9
+ assert.ok(route);
10
+ });
11
+ });
@@ -1,21 +1,21 @@
1
- class SidekiqLogsterReporter
2
- def call(ex, context = {})
3
- # Pass context to Logster
4
- fake_env = {}
5
- context.each do |key, value|
6
- Logster.add_to_env(fake_env, key, value)
7
- end
8
-
9
- text = "Job exception: #{ex}\n"
10
- if ex.backtrace
11
- Logster.add_to_env(fake_env, :backtrace, ex.backtrace)
12
- end
13
-
14
- Thread.current[Logster::Logger::LOGSTER_ENV] = fake_env
15
- Logster.logger.error(text)
16
- rescue => e
17
- Logster.logger.fatal("Failed to log exception #{ex} #{hash}\nReason: #{e.class} #{e}\n#{e.backtrace.join("\n")}")
18
- ensure
19
- Thread.current[Logster::Logger::LOGSTER_ENV] = nil
20
- end
21
- end
1
+ class SidekiqLogsterReporter
2
+ def call(ex, context = {})
3
+ # Pass context to Logster
4
+ fake_env = {}
5
+ context.each do |key, value|
6
+ Logster.add_to_env(fake_env, key, value)
7
+ end
8
+
9
+ text = "Job exception: #{ex}\n"
10
+ if ex.backtrace
11
+ Logster.add_to_env(fake_env, :backtrace, ex.backtrace)
12
+ end
13
+
14
+ Thread.current[Logster::Logger::LOGSTER_ENV] = fake_env
15
+ Logster.logger.error(text)
16
+ rescue => e
17
+ Logster.logger.fatal("Failed to log exception #{ex} #{hash}\nReason: #{e.class} #{e}\n#{e.backtrace.join("\n")}")
18
+ ensure
19
+ Thread.current[Logster::Logger::LOGSTER_ENV] = nil
20
+ end
21
+ end
@@ -1,54 +1,54 @@
1
- require 'logster/logger'
2
- require 'logster/message'
3
- require 'logster/configuration'
4
- require 'logster/web'
5
- require 'logster/ignore_pattern'
6
-
7
- if defined? Redis
8
- require 'logster/redis_store'
9
- else
10
- STDERR.puts "ERROR: Redis is not loaded, ensure redis gem is required before logster"
11
- exit
12
- end
13
-
14
- module Logster
15
- def self.logger=(logger)
16
- @logger = logger
17
- end
18
-
19
- def self.logger
20
- @logger
21
- end
22
-
23
- def self.store=(store)
24
- @store = store
25
- end
26
-
27
- def self.store
28
- @store
29
- end
30
-
31
- def self.config=(config)
32
- @config = config
33
- end
34
-
35
- def self.config
36
- @config ||= Configuration.new
37
- end
38
-
39
- def self.add_to_env(env, key, value)
40
- logster_env = Logster::Message.populate_from_env(env)
41
- logster_env[key] = value
42
- end
43
-
44
- def self.set_environments(envs)
45
- config.environments = envs
46
- end
47
- end
48
-
49
- # check logster/configuration.rb for config options
50
- # Logster.config.environments << :staging
51
-
52
- if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i >= 3
53
- require 'logster/rails/railtie'
54
- end
1
+ require 'logster/logger'
2
+ require 'logster/message'
3
+ require 'logster/configuration'
4
+ require 'logster/web'
5
+ require 'logster/ignore_pattern'
6
+
7
+ if defined? Redis
8
+ require 'logster/redis_store'
9
+ else
10
+ STDERR.puts "ERROR: Redis is not loaded, ensure redis gem is required before logster"
11
+ exit
12
+ end
13
+
14
+ module Logster
15
+ def self.logger=(logger)
16
+ @logger = logger
17
+ end
18
+
19
+ def self.logger
20
+ @logger
21
+ end
22
+
23
+ def self.store=(store)
24
+ @store = store
25
+ end
26
+
27
+ def self.store
28
+ @store
29
+ end
30
+
31
+ def self.config=(config)
32
+ @config = config
33
+ end
34
+
35
+ def self.config
36
+ @config ||= Configuration.new
37
+ end
38
+
39
+ def self.add_to_env(env, key, value)
40
+ logster_env = Logster::Message.populate_from_env(env)
41
+ logster_env[key] = value
42
+ end
43
+
44
+ def self.set_environments(envs)
45
+ config.environments = envs
46
+ end
47
+ end
48
+
49
+ # check logster/configuration.rb for config options
50
+ # Logster.config.environments << :staging
51
+
52
+ if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i >= 3
53
+ require 'logster/rails/railtie'
54
+ end
@@ -1,141 +1,141 @@
1
- module Logster
2
- class BaseStore
3
-
4
- attr_accessor :level, :max_retention, :skip_empty, :ignore
5
-
6
- def initialize
7
- @max_retention = 60 * 60 * 24 * 7
8
- @skip_empty = true
9
- end
10
-
11
- # Save a new message at the front of the latest list.
12
- def save(message)
13
- not_implemented
14
- end
15
-
16
- # Modify the saved message to the given one (identified by message.key) and bump it to the top of the latest list
17
- def replace_and_bump(message, save_env: true)
18
- not_implemented
19
- end
20
-
21
- # Check if another message with the same grouping_key is already stored.
22
- # Returns the similar message's message.key
23
- def similar_key(message)
24
- not_implemented
25
- end
26
-
27
- # The number of messages currently stored.
28
- def count
29
- not_implemented
30
- end
31
-
32
- # Delete all unprotected messages in the store.
33
- def clear
34
- not_implemented
35
- end
36
-
37
- # Delete all messages, including protected messages.
38
- def clear_all
39
- not_implemented
40
- end
41
-
42
- # Get a message by its message_key
43
- def get(message_key, load_env: true)
44
- not_implemented
45
- end
46
-
47
- # Get a group of messages by their message_keys
48
- def bulk_get(message_keys)
49
- not_implemented
50
- end
51
-
52
- # Get a message's env by its message_key
53
- def get_env(message_key)
54
- not_implemented
55
- end
56
-
57
- # Mark a message as protected; i.e. it is not deleted by the #clear method
58
- def protect(message_key)
59
- not_implemented
60
- end
61
-
62
- def delete(message_key)
63
- not_implemented
64
- end
65
-
66
- # Clear the protected mark for a message.
67
- def unprotect(message_key)
68
- not_implemented
69
- end
70
-
71
- # Solve a particular message, causing all old messages with matching version and backtrace
72
- # to be deleted (report should delete any solved messages when called)
73
- def solve(message_key)
74
- not_implemented
75
- end
76
-
77
- # Registers a rate limit on the given severities of logs
78
- def register_rate_limit(severities, limit, duration, &block)
79
- not_implemented
80
- end
81
-
82
- # Checks all the existing rate limiters to check if any has been exceeded
83
- def check_rate_limits(severity)
84
- not_implemented
85
- end
86
-
87
- def report(severity, progname, msg, opts = {})
88
- return if (!msg || (String === msg && msg.empty?)) && skip_empty
89
- return if level && severity < level
90
-
91
- message = Logster::Message.new(severity, progname, msg, opts[:timestamp], count: opts[:count])
92
-
93
- env = opts[:env] || {}
94
- backtrace = opts[:backtrace]
95
- if Hash === env && env[:backtrace]
96
- # Special - passing backtrace through env
97
- backtrace = env.delete(:backtrace)
98
- end
99
-
100
- message.populate_from_env(env)
101
-
102
- if backtrace
103
- if backtrace.respond_to? :join
104
- backtrace = backtrace.join("\n")
105
- end
106
- message.backtrace = backtrace
107
- else
108
- message.backtrace = caller.join("\n")
109
- end
110
-
111
- return if ignore && ignore.any? { |pattern| message =~ pattern }
112
-
113
- similar = nil
114
-
115
- if Logster.config.allow_grouping
116
- key = self.similar_key(message)
117
- similar = get(key, load_env: false) if key
118
- end
119
-
120
- if similar
121
- has_env = !similar.env.nil? && !similar.env.empty?
122
- if similar.count < Logster::MAX_GROUPING_LENGTH && !has_env
123
- similar.env = get_env(similar.key) || {}
124
- end
125
- save_env = similar.merge_similar_message(message)
126
-
127
- replace_and_bump(similar, save_env: save_env || has_env)
128
- similar
129
- else
130
- save message
131
- message
132
- end
133
- end
134
-
135
- private
136
-
137
- def not_implemented
138
- raise "Not Implemented"
139
- end
140
- end
141
- end
1
+ module Logster
2
+ class BaseStore
3
+
4
+ attr_accessor :level, :max_retention, :skip_empty, :ignore
5
+
6
+ def initialize
7
+ @max_retention = 60 * 60 * 24 * 7
8
+ @skip_empty = true
9
+ end
10
+
11
+ # Save a new message at the front of the latest list.
12
+ def save(message)
13
+ not_implemented
14
+ end
15
+
16
+ # Modify the saved message to the given one (identified by message.key) and bump it to the top of the latest list
17
+ def replace_and_bump(message, save_env: true)
18
+ not_implemented
19
+ end
20
+
21
+ # Check if another message with the same grouping_key is already stored.
22
+ # Returns the similar message's message.key
23
+ def similar_key(message)
24
+ not_implemented
25
+ end
26
+
27
+ # The number of messages currently stored.
28
+ def count
29
+ not_implemented
30
+ end
31
+
32
+ # Delete all unprotected messages in the store.
33
+ def clear
34
+ not_implemented
35
+ end
36
+
37
+ # Delete all messages, including protected messages.
38
+ def clear_all
39
+ not_implemented
40
+ end
41
+
42
+ # Get a message by its message_key
43
+ def get(message_key, load_env: true)
44
+ not_implemented
45
+ end
46
+
47
+ # Get a group of messages by their message_keys
48
+ def bulk_get(message_keys)
49
+ not_implemented
50
+ end
51
+
52
+ # Get a message's env by its message_key
53
+ def get_env(message_key)
54
+ not_implemented
55
+ end
56
+
57
+ # Mark a message as protected; i.e. it is not deleted by the #clear method
58
+ def protect(message_key)
59
+ not_implemented
60
+ end
61
+
62
+ def delete(message_key)
63
+ not_implemented
64
+ end
65
+
66
+ # Clear the protected mark for a message.
67
+ def unprotect(message_key)
68
+ not_implemented
69
+ end
70
+
71
+ # Solve a particular message, causing all old messages with matching version and backtrace
72
+ # to be deleted (report should delete any solved messages when called)
73
+ def solve(message_key)
74
+ not_implemented
75
+ end
76
+
77
+ # Registers a rate limit on the given severities of logs
78
+ def register_rate_limit(severities, limit, duration, &block)
79
+ not_implemented
80
+ end
81
+
82
+ # Checks all the existing rate limiters to check if any has been exceeded
83
+ def check_rate_limits(severity)
84
+ not_implemented
85
+ end
86
+
87
+ def report(severity, progname, msg, opts = {})
88
+ return if (!msg || (String === msg && msg.empty?)) && skip_empty
89
+ return if level && severity < level
90
+
91
+ message = Logster::Message.new(severity, progname, msg, opts[:timestamp], count: opts[:count])
92
+
93
+ env = opts[:env] || {}
94
+ backtrace = opts[:backtrace]
95
+ if Hash === env && env[:backtrace]
96
+ # Special - passing backtrace through env
97
+ backtrace = env.delete(:backtrace)
98
+ end
99
+
100
+ message.populate_from_env(env)
101
+
102
+ if backtrace
103
+ if backtrace.respond_to? :join
104
+ backtrace = backtrace.join("\n")
105
+ end
106
+ message.backtrace = backtrace
107
+ else
108
+ message.backtrace = caller.join("\n")
109
+ end
110
+
111
+ return if ignore && ignore.any? { |pattern| message =~ pattern }
112
+
113
+ similar = nil
114
+
115
+ if Logster.config.allow_grouping
116
+ key = self.similar_key(message)
117
+ similar = get(key, load_env: false) if key
118
+ end
119
+
120
+ if similar
121
+ has_env = !similar.env.nil? && !similar.env.empty?
122
+ if similar.count < Logster::MAX_GROUPING_LENGTH && !has_env
123
+ similar.env = get_env(similar.key) || {}
124
+ end
125
+ save_env = similar.merge_similar_message(message)
126
+
127
+ replace_and_bump(similar, save_env: save_env || has_env)
128
+ similar
129
+ else
130
+ save message
131
+ message
132
+ end
133
+ end
134
+
135
+ private
136
+
137
+ def not_implemented
138
+ raise "Not Implemented"
139
+ end
140
+ end
141
+ end