Skip to content

Commit b72c36b

Browse files
committed
Merge remote-tracking branch 'upstream/master' into update-log-error
2 parents bcb5f8d + 6e1291f commit b72c36b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1017
-197
lines changed

.github/FUNDING.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# These are supported funding model platforms
2+
3+
github: reidmorrison

.github/workflows/ci.yml

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,34 @@ jobs:
1212
fail-fast: false
1313
matrix:
1414
include:
15-
- rails: 5.1
16-
ruby: 2.5
17-
18-
- rails: 5.2
19-
ruby: 2.5
20-
- rails: 5.2
21-
ruby: 2.6
22-
- rails: 5.2
23-
ruby: jruby-9.3
24-
25-
- rails: "6.0"
26-
ruby: 2.6
27-
- rails: "6.0"
28-
ruby: 2.7
2915
- rails: "6.0"
30-
ruby: jruby
16+
ruby: "2.7"
3117

3218
- rails: "6.1"
3319
ruby: "2.7"
3420
- rails: "6.1"
35-
ruby: jruby
36-
37-
- rails: "7.0"
3821
ruby: "3.0"
22+
- rails: "6.1"
23+
ruby: "3.1"
24+
- rails: "6.1"
25+
ruby: "3.2"
26+
3927
- rails: "7.0"
40-
ruby: 3.1
41-
- rails: "7.0"
42-
ruby: 3.2
43-
- rails: "7.0"
44-
ruby: jruby
28+
ruby: "3.1"
29+
- rails: "7.0b"
30+
ruby: "3.2"
31+
32+
- rails: "7.1"
33+
ruby: "3.1"
34+
- rails: "7.1b"
35+
ruby: "3.1"
36+
- rails: "7.1.1"
37+
ruby: "3.2"
38+
- rails: "7.1"
39+
ruby: "3.2"
40+
41+
- rails: "7.2"
42+
ruby: "3.3"
4543

4644
env:
4745
BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.rails }}.gemfile

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.log
33
pkg/
44
test/dummy/tmp/
5+
test/dummy/db/test.sqlite3-*
56
test/dummy/.sass-cache
67
*.gem
78
/.idea
@@ -12,6 +13,7 @@ Gemfile.lock
1213

1314
*.sqlite3
1415
.rakeTasks
15-
*.sqlite3
1616
TODO.md
1717

18+
.tool-versions
19+
test/dummy/db/test.sqlite3

.rubocop.yml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
AllCops:
2-
TargetRubyVersion: 2.4
32
Exclude:
4-
- '.git/**/*'
5-
- '.github/**/*'
6-
- 'gemfiles/**/*'
3+
- ".git/**/*"
4+
- "docs/**/*"
5+
- "gemfiles/*"
6+
NewCops: enable
7+
TargetRubyVersion: 2.5
78

89
#
910
# RuboCop built-in settings.
@@ -31,7 +32,7 @@ Layout/HashAlignment:
3132
Layout/LineLength:
3233
Max: 128
3334
Exclude:
34-
- '**/test/**/*'
35+
- "**/test/**/*"
3536

3637
# Match existing layout
3738
Layout/SpaceInsideHashLiteralBraces:
@@ -44,17 +45,17 @@ Metrics/AbcSize:
4445
# Support long block lengths for tests
4546
Metrics/BlockLength:
4647
Exclude:
47-
- 'test/**/*'
48-
- '**/*/cli.rb'
49-
ExcludedMethods:
50-
- 'aasm'
51-
- 'included'
48+
- "test/**/*"
49+
- "**/*/cli.rb"
50+
AllowedMethods:
51+
- "aasm"
52+
- "included"
5253

5354
# Soften limits
5455
Metrics/ClassLength:
5556
Max: 250
5657
Exclude:
57-
- 'test/**/*'
58+
- "test/**/*"
5859

5960
# TODO: Soften Limits for phase 1 only
6061
Metrics/CyclomaticComplexity:
@@ -77,15 +78,15 @@ Metrics/PerceivedComplexity:
7778

7879
# Initialization Vector abbreviation
7980
Naming/MethodParameterName:
80-
AllowedNames: ['iv', '_', 'io', 'ap']
81+
AllowedNames: [ "iv", "_", "io", "ap", "id", "_id" ]
8182

8283
# Does not allow Symbols to load
8384
Security/YAMLLoad:
8485
AutoCorrect: false
8586

8687
# Needed for testing DateTime
8788
Style/DateTime:
88-
Exclude: ['test/**/*']
89+
Exclude: [ "test/**/*" ]
8990

9091
# TODO: Soften Limits for phase 1 only
9192
Style/Documentation:

Appraisals

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,46 @@
1-
appraise "rails_5.1" do
2-
gem "rails", "~> 5.1.5"
3-
gem "sqlite3", "~> 1.3.0", platform: :ruby
4-
gem "activerecord-jdbcsqlite3-adapter", "~> 51.0", platform: :jruby
5-
end
6-
7-
appraise "rails_5.2" do
8-
gem "rails", "~> 5.2.0"
9-
gem "sqlite3", "~> 1.3.0", platform: :ruby
10-
gem "activerecord-jdbcsqlite3-adapter", "~> 52.0", platform: :jruby
11-
end
12-
131
appraise "rails_6.0" do
142
gem "rails", "~> 6.0.0"
15-
gem "activerecord-jdbcsqlite3-adapter", "~> 60.0", platform: :jruby
16-
gem "sqlite3", "~> 1.4.0", platform: :ruby
3+
gem "sidekiq", "~> 4.2"
4+
gem "sqlite3", "~> 1.4"
175
end
186

197
appraise "rails_6.1" do
208
gem "rails", "~> 6.1.0"
21-
gem "activerecord-jdbcsqlite3-adapter", "~> 61.0", platform: :jruby
22-
gem "sqlite3", "~> 1.4.0", platform: :ruby
9+
gem "sidekiq", "~> 5.2"
10+
gem "sqlite3", "~> 1.4"
2311
end
2412

2513
appraise "rails_7.0" do
26-
# Remove this deprecated gem once the following patch is released
27-
# https://github.com/rails-api/active_model_serializers/pull/2428
28-
gem "thread_safe", "~> 0.3.6"
14+
gem "rails", "~> 7.0.0"
15+
gem "sidekiq", "~> 6.2.0"
16+
gem "sqlite3", "~> 1.4"
17+
end
2918

19+
appraise "rails_7.0b" do
3020
gem "rails", "~> 7.0.0"
31-
gem "activerecord-jdbcsqlite3-adapter", "~> 70.0", platform: :jruby
32-
gem "sqlite3", "~> 1.4.0", platform: :ruby
21+
gem "sidekiq", "~> 6.5"
22+
gem "sqlite3", "~> 1.4"
23+
end
24+
25+
appraise "rails_7.1.1" do
26+
gem "rails", "7.1.1"
27+
gem "sidekiq", "~> 7.0.9"
28+
gem "sqlite3", "~> 1.4"
29+
end
30+
31+
appraise "rails_7.1" do
32+
gem "rails", "~> 7.1.0"
33+
gem "sidekiq", "~> 7.1.6"
34+
gem "sqlite3", "~> 1.4"
35+
end
36+
37+
appraise "rails_7.1b" do
38+
gem "rails", "~> 7.1.0"
39+
gem "sidekiq", "~> 7.3.0"
40+
gem "sqlite3", "~> 1.4"
41+
end
42+
43+
appraise "rails_7.2" do
44+
gem "rails", "~> 7.2.0.beta2"
45+
gem "sidekiq", "~> 7.2.4"
3346
end

Gemfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ gem "minitest-rails"
1212
gem "rake"
1313
gem "sprockets", "< 4.0"
1414

15-
gem "rails", "~> 7.0.0"
16-
gem "sqlite3", "~> 1.4.0", platform: :ruby
15+
gem "rails", "~> 7.2.0.beta2"
16+
gem "sidekiq", "~> 7.2.4"
17+
gem "sqlite3"
1718

1819
gem "rubocop"

README.md

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,116 @@
33

44
Rails Semantic Logger replaces the Rails default logger with [Semantic Logger](https://logger.rocketjob.io/)
55

6+
When any large Rails application is deployed to production one of the first steps is to move to centralized logging, so that logs can be viewed and searched from a central location.
7+
8+
Centralized logging quickly falls apart when trying to consume the current human readable log files:
9+
- Log entries often span multiple lines, resulting in unrelated log lines in the centralized logging system. For example, stack traces.
10+
- Complex Regular Expressions are needed to parse the text lines and make them machine readable. For example to build queries, or alerts that are looking for specific elements in the message.
11+
- Writing searches, alerts, or dashboards based on text logs is incredibly brittle, since a small change to the text logged can often break the parsing of those logs.
12+
- Every log entry often has a completely different format, making it difficult to make consistent searches against the data.
13+
14+
For these and many other reasons switching to structured logging, or logs in JSON format, in testing and production makes centralized logging incredibly powerful.
15+
16+
For example, adding these lines to `config/application.rb` and removing any other log overrides from other environments, will switch automatically to structured logging when running inside Kubernetes:
17+
~~~ruby
18+
# Setup structured logging
19+
config.semantic_logger.application = "my_application"
20+
config.semantic_logger.environment = ENV["STACK_NAME"] || Rails.env
21+
config.log_level = ENV["LOG_LEVEL"] || :info
22+
23+
# Switch to JSON Logging output to stdout when running on Kubernetes
24+
if ENV["LOG_TO_CONSOLE"] || ENV["KUBERNETES_SERVICE_HOST"]
25+
config.rails_semantic_logger.add_file_appender = false
26+
config.semantic_logger.add_appender(io: $stdout, formatter: :json)
27+
end
28+
~~~
29+
30+
Then configure the centralized logging system to tell it that the data is in JSON format, so that it will parse it for you into a hierarchy.
31+
32+
For example, the following will instruct [Observe](https://www.observeinc.com/) to parse the JSON data and create machine readable data from it:
33+
~~~ruby
34+
interface "log", "log":log
35+
36+
make_col event:parse_json(log)
37+
38+
make_col
39+
time:parse_isotime(event.timestamp),
40+
application:string(event.application),
41+
environment:string(event.environment),
42+
duration:duration_ms(event.duration_ms),
43+
level:string(event.level),
44+
name:string(event.name),
45+
message:string(event.message),
46+
named_tags:event.named_tags,
47+
payload:event.payload,
48+
metric:string(event.metric),
49+
metric_amount:float64(event.metric_amount),
50+
tags:array(event.tags),
51+
exception:event.exception,
52+
host:string(event.host),
53+
pid:int64(event.pid),
54+
thread:string(event.thread),
55+
file:string(event.file),
56+
line:int64(event.line),
57+
dimensions:event.dimensions,
58+
backtrace:array(event.backtrace),
59+
level_index:int64(event.level_index)
60+
61+
set_valid_from(time)
62+
drop_col timestamp, log, event, stream
63+
rename_col timestamp:time
64+
~~~
65+
66+
Now queries can be built to drill down into each of these fields, including `payload` which is a nested object.
67+
68+
For example to find all failed Sidekiq job calls where the causing exception class name is `NoMethodError`:
69+
~~~ruby
70+
filter environment = "uat2"
71+
filter level = "error"
72+
filter metric = "sidekiq.job.perform"
73+
filter (string(exception.cause.name) = "NoMethodError")
74+
~~~
75+
76+
Example: create a dashboard showing the duration of all successful Sidekiq jobs:
77+
~~~ruby
78+
filter environment = "production"
79+
filter level = "info"
80+
filter metric = "sidekiq.job.perform"
81+
timechart duration:avg(duration), group_by(name)
82+
~~~
83+
84+
Example: create a dashboard showing the queue latency of all Sidekiq jobs.
85+
The queue latency is the time between when the job was enqueued and when it was started:
86+
~~~ruby
87+
filter environment = "production"
88+
filter level = "info"
89+
filter metric = "sidekiq.queue.latency"
90+
timechart latency:avg(metric_amount/1000), group_by(string(named_tags.queue))
91+
~~~
92+
693
* http://github.com/reidmorrison/rails_semantic_logger
794

895
## Documentation
996

1097
For complete documentation see: https://logger.rocketjob.io/rails
1198

99+
## Upgrading to Semantic Logger V4.16 - Sidekiq Metrics Support
100+
101+
Rails Semantic Logger now supports Sidekiq metrics.
102+
Below are the metrics that are now available when the JSON logging format is used:
103+
- `sidekiq.job.perform`
104+
- The duration of each Sidekiq job.
105+
- `duration` contains the time in milliseconds that the job took to run.
106+
- `sidekiq.queue.latency`
107+
- The time between when a Sidekiq job was enqueued and when it was started.
108+
- `metric_amount` contains the time in milliseconds that the job was waiting in the queue.
109+
110+
## Upgrading to Semantic Logger v4.15 & V4.16 - Sidekiq Support
111+
112+
Rails Semantic Logger introduces direct support for Sidekiq v4, v5, v6, and v7.
113+
Please remove any previous custom patches or configurations to make Sidekiq work with Semantic Logger.
114+
To see the complete list of patches being made, and to contribute your own changes, see: [Sidekiq Patches](https://github.com/reidmorrison/rails_semantic_logger/blob/master/lib/rails_semantic_logger/extensions/sidekiq/sidekiq.rb)
115+
12116
## Upgrading to Semantic Logger v4.4
13117

14118
With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
@@ -19,7 +123,18 @@ I.e. Please remove the following line if being called anywhere:
19123
SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
20124
~~~
21125

22-
## Supports
126+
## New Versions of Rails, etc.
127+
128+
The primary purpose of the Rails Semantic Logger gem is to patch other gems, primarily Rails, to make them support structured logging though Semantic Logger.
129+
130+
When new versions of Rails and other gems are published they often make changes to the internals, so the existing patches stop working.
131+
132+
Rails Semantic Logger survives only when someone in the community upgrades to a newer Rails or other supported libraries, runs into problems,
133+
and then contributes the fix back to the community by means of a pull request.
134+
135+
Additionally, when new popular gems come out, we rely only the community to supply the necessary patches in Rails Semantic Logger to make those gems support structured logging.
136+
137+
## Supported Platforms
23138

24139
For the complete list of supported Ruby and Rails versions, see the [Testing file](https://github.com/reidmorrison/rails_semantic_logger/blob/master/.github/workflows/ci.yml).
25140

gemfiles/rails_6.0.gemfile

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ gem "minitest"
1010
gem "minitest-rails"
1111
gem "rake"
1212
gem "sprockets", "< 4.0"
13-
gem "semantic_logger", github: "reidmorrison/semantic_logger"
1413
gem "rails", "~> 6.0.0"
15-
gem "sqlite3", "~> 1.4.0", platform: :ruby
16-
gem "activerecord-jdbcsqlite3-adapter", "~> 60.0", platform: :jruby
17-
18-
group :development do
19-
gem "rubocop"
20-
end
14+
gem "sidekiq", "~> 4.2"
15+
gem "sqlite3", "~> 1.4"
16+
gem "rubocop"
2117

2218
gemspec path: "../"

gemfiles/rails_6.1.gemfile

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ gem "minitest"
1010
gem "minitest-rails"
1111
gem "rake"
1212
gem "sprockets", "< 4.0"
13-
gem "semantic_logger", github: "reidmorrison/semantic_logger"
1413
gem "rails", "~> 6.1.0"
15-
gem "sqlite3", "~> 1.4.0", platform: :ruby
16-
gem "activerecord-jdbcsqlite3-adapter", "~> 61.0", platform: :jruby
17-
18-
group :development do
19-
gem "rubocop"
20-
end
14+
gem "sidekiq", "~> 5.2"
15+
gem "sqlite3", "~> 1.4"
16+
gem "rubocop"
2117

2218
gemspec path: "../"

0 commit comments

Comments
 (0)