fluent_logger_rails 0.1.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a88bc428967e9ee7c2f81f9e747b0cc868f52fe9158587c4c847f1516c43d59
4
- data.tar.gz: 175d618a1cc6cd67e7c137b02328040e256c8f8e101e6d8786501227792453fe
3
+ metadata.gz: 03bf0245f30becb0ca43fd78ee5470cfa5f20bf9b4e5f06e9168afb9e9085b04
4
+ data.tar.gz: 52c576538ac4e5c026a4ef0002b3fb1949ed5a82bd8b4a2f2a4ac9d1536304c3
5
5
  SHA512:
6
- metadata.gz: a1557f1bb328c7525b9c7341898c8cfeebe4646a1b2d0741b09cc7e65ae3e2e1de6654b59d8abd1b50818b9e94c2ddc8c95fd3bb40c9d08daf3d632cdf74f11b
7
- data.tar.gz: ad952d449c9c9e53e3ac59da6da928cb1a34fd01fa4d34d9a2fce3d4160a48b3cca22fe75517b8b62144ae21a878e962abc915a21a97446bb9bc9919a79d6687
6
+ metadata.gz: 9a532ebb712a7b5cd3c717a708f60eb7824a373b202f2c551123380d753c40b328cbbe07cb618ef69f70147f557c51e1c61a9e57060d2b2f6a35d2d74b43b103
7
+ data.tar.gz: be04095c6e2d93bef662ac067fc6f054849c97bca4d3919fd1c9dfd2ebacb68563e951da9294ac8bdd1cddd46990b815c6e882d789219a07479f20869521b063
@@ -0,0 +1,28 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: 2.6
25
+ - name: Install dependencies
26
+ run: bundle install
27
+ - name: Run tests
28
+ run: bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -8,9 +8,74 @@ Bug Fixes:
8
8
 
9
9
  Enhancements:
10
10
 
11
- * Add a rake task to walk through your table/columns and easily classify and create a migration from it
12
- * Add a migration generator
13
- * Module helper to include in migrations to add data classification smart comment
11
+ * None
12
+
13
+ Deprecations:
14
+ * None
15
+
16
+ ## v.0.5.0
17
+
18
+ Bug Fixes:
19
+
20
+ * None
21
+
22
+ Enhancements:
23
+
24
+ * Add option to allow message to be merged into payload (#8)
25
+
26
+ Deprecations:
27
+
28
+ * None
29
+
30
+ ## v0.4.0
31
+
32
+ Bug Fixes:
33
+
34
+ * None
35
+
36
+ Enhancements:
37
+
38
+ * Support for all Rails 6 version (#7)
39
+
40
+ Deprecations:
41
+
42
+ * None
43
+
44
+ ## v0.3.1
45
+
46
+ Bug Fixes:
47
+
48
+ * None
49
+
50
+ Enhancements:
51
+
52
+ * Fix deprecation warning for Rails 6 (#4)
53
+
54
+ Deprecations:
55
+ * None
56
+
57
+ ## v0.3.0
58
+
59
+ Bug Fixes:
60
+
61
+ * None
62
+
63
+ Enhancements:
64
+
65
+ * Support for Rails 6 (#3)
66
+
67
+ Deprecations:
68
+ * None
69
+
70
+ ## v0.2.0
71
+
72
+ Bug Fixes:
73
+
74
+ * None
75
+
76
+ Enhancements:
77
+
78
+ * Refactoring interface, major breaking changes on format (#1)
14
79
 
15
80
  Deprecations:
16
81
  * None
data/Gemfile.lock CHANGED
@@ -1,24 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent_logger_rails (0.1.0)
5
- activesupport (~> 5.0)
4
+ fluent_logger_rails (0.5.0)
5
+ activesupport (>= 5.0, < 7)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activesupport (5.2.4.3)
10
+ activesupport (6.1.0)
11
11
  concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (>= 0.7, < 2)
13
- minitest (~> 5.1)
14
- tzinfo (~> 1.1)
12
+ i18n (>= 1.6, < 2)
13
+ minitest (>= 5.1)
14
+ tzinfo (~> 2.0)
15
+ zeitwerk (~> 2.3)
15
16
  coderay (1.1.3)
16
- concurrent-ruby (1.1.6)
17
+ concurrent-ruby (1.1.7)
17
18
  diff-lcs (1.4.4)
18
- i18n (1.8.3)
19
+ i18n (1.8.5)
19
20
  concurrent-ruby (~> 1.0)
20
21
  method_source (1.0.0)
21
- minitest (5.14.1)
22
+ minitest (5.14.2)
22
23
  pry (0.13.1)
23
24
  coderay (~> 1.1)
24
25
  method_source (~> 1.0)
@@ -35,10 +36,10 @@ GEM
35
36
  diff-lcs (>= 1.2.0, < 2.0)
36
37
  rspec-support (~> 3.9.0)
37
38
  rspec-support (3.9.3)
38
- thread_safe (0.3.6)
39
39
  timecop (0.9.1)
40
- tzinfo (1.2.7)
41
- thread_safe (~> 0.1)
40
+ tzinfo (2.0.3)
41
+ concurrent-ruby (~> 1.0)
42
+ zeitwerk (2.4.2)
42
43
 
43
44
  PLATFORMS
44
45
  ruby
@@ -50,4 +51,4 @@ DEPENDENCIES
50
51
  timecop
51
52
 
52
53
  BUNDLED WITH
53
- 1.17.2
54
+ 2.1.4
data/README.md CHANGED
@@ -0,0 +1,109 @@
1
+ # Fluent Logger Rails
2
+
3
+ This is a library that wraps the [fluent-logger gem](https://github.com/fluent/fluent-logger-ruby) and provides easy integration with your Rails application. This includes a log formatter that supports [Rails tagged logging](https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html) so your output JSON format that can be sent to Fluentd (or really any other logging backend).
4
+
5
+ # Installation
6
+
7
+ ```
8
+ gem install fluent_logger_rails
9
+ ```
10
+
11
+ # How to configure
12
+
13
+ ```ruby
14
+ Rails.application.configure do
15
+ config.logger = FluentLoggerRails::Logger.new(
16
+ ::Fluent::Logger::FluentLogger.new(
17
+ nil,
18
+ host: 'localhost',
19
+ port: 24224,
20
+ ),
21
+ level: config.log_level
22
+ )
23
+ # if you are using tagged logging, you need a formatter that supports it
24
+ config.logger.formatter = FluentLoggerRails::TaggedHashFormatter.new
25
+ end
26
+ ```
27
+
28
+ ## Formatter Configuration
29
+
30
+ This gem includes a formatter that supports [Rails tagged logging](https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html).
31
+
32
+ ### Hash aka JSON logger formatter
33
+
34
+ This is a JSON formatter that supports tagged logging.
35
+ ```ruby
36
+ config.logger.formatter = FluentLoggerRails::TaggedHashFormatter.new
37
+ config.logger.formatter.datetime_format = '%Y-%m-%d %H:%M:%S.%3N%z'
38
+ config.logger.formatter.parent_key = 'payload'
39
+ ```
40
+
41
+ ### Standard Rails Tagged Logger aka default logger format
42
+
43
+ The standard Rails tagged logger works as well for standard output.
44
+ ```ruby
45
+ ActiveSupport::TaggedLogging.new(config.logger)
46
+ ```
47
+
48
+ # Examples
49
+
50
+ ## Hash formatter with tagged Logging
51
+ ```ruby
52
+ Rails.logger.tagged(user.id) do
53
+ Rails.logger.warn('UserUpdateJob failed')
54
+ end
55
+
56
+ #
57
+ # Outputs:
58
+ #
59
+ # {
60
+ # "tags": [1234],
61
+ # "message": "UserUpdateJob failed",
62
+ # "severity": "WARN",
63
+ # "timestamp": "2019-01-08 14:51:39.701-0800",
64
+ # }
65
+ ```
66
+
67
+ ## Hash formatter with hash tagged Logging
68
+
69
+ ```ruby
70
+ Rails.logger.tagged(user_id: user.id, session_id: user_session.id) do
71
+ Rails.logger.info(message: 'UserUpdateJob failed', args: args)
72
+ end
73
+
74
+ #
75
+ # Outputs:
76
+ #
77
+ # {
78
+ # "user_id": 1234,
79
+ # "session_id": 883839,
80
+ # "message": {
81
+ # "message": "UserUpdateJob failed",
82
+ # "args": [1,2,3]
83
+ # },
84
+ # "severity": "INFO",
85
+ # "timestamp": "2019-01-08 14:51:39.701-0800",
86
+ # }
87
+ ```
88
+
89
+ ## Standard Rails formatter with tagged Logger
90
+
91
+ ```ruby
92
+ Rails.logger.tagged(user.id, user_session.id) do
93
+ Rails.logger.info('UserUpdateJob failed')
94
+ end
95
+
96
+ #
97
+ # Outputs:
98
+ #
99
+ # [1234] [883839] UserUpdateJob failed
100
+ ```
101
+
102
+ # How to test this locally
103
+
104
+ You can setup Fluentd with ruby gems as described on [Fluentd docs](https://docs.fluentd.org/installation/install-by-gem). Once that is running, simply configure your environment with the example above and the logs should appear.
105
+
106
+ # Related Projects
107
+
108
+ - https://github.com/fluent/fluent-logger-ruby
109
+ - https://github.com/actindi/act-fluent-logger-rails
@@ -5,8 +5,11 @@ Gem::Specification.new do |spec|
5
5
  spec.name = 'fluent_logger_rails'
6
6
  spec.version = FluentLoggerRails::VERSION
7
7
  spec.date = '2020-07-14'
8
- spec.summary = "A wrapper for fluent-logger gem to support tagged logging"
9
- spec.description = "A simple hello world gem"
8
+ spec.summary = "A wrapper for fluent-logger gem with support for tagged logging"
9
+ spec.description = "This is a library that wraps the [fluent-logger gem](https://github.com/fluent/fluent-logger-ruby) "\
10
+ "and provides easy integration with your Rails application. This includes log formatters that support "\
11
+ "[Rails tagged logging](https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html) for JSON format "\
12
+ "that can be sent to Fluentd (or really any other logging backend)."
10
13
  spec.authors = ["HackerOne Open Source", "Ben Willis"]
11
14
  spec.email = ["opensource+fluent_logger_rails@hackerone.com", "ben@hackeroen.com"]
12
15
  spec.homepage = "https://github.com/Hacker0x01/fluent_logger_rails"
@@ -14,7 +17,7 @@ Gem::Specification.new do |spec|
14
17
  spec.license = "MIT"
15
18
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
16
19
 
17
- spec.add_dependency('activesupport', '~> 5.0')
20
+ spec.add_dependency('activesupport', '>= 5.0', '< 7')
18
21
 
19
22
  spec.add_development_dependency 'rspec', '~> 3.6'
20
23
  spec.add_development_dependency 'timecop'
@@ -1,5 +1,2 @@
1
1
  require 'fluent_logger_rails/logger'
2
- require 'fluent_logger_rails/tagged_logging'
3
- require 'fluent_logger_rails/hash_formatter'
4
- require 'fluent_logger_rails/json_formatter'
5
- require 'fluent_logger_rails/pretty_json_formatter'
2
+ require 'fluent_logger_rails/tagged_hash_formatter'
@@ -7,7 +7,7 @@ module FluentLoggerRails
7
7
  @level = SEV_LABEL.index(level.to_s.upcase)
8
8
  @path = path
9
9
  @logger = logger
10
- after_initialize if respond_to? :after_initialize
10
+ after_initialize if respond_to?(:after_initialize) && ActiveSupport::VERSION::MAJOR < 6
11
11
  end
12
12
 
13
13
  def add(severity, message = nil, progname = nil)
@@ -16,8 +16,7 @@ module FluentLoggerRails
16
16
  message = (block_given? ? yield : progname) if message.blank?
17
17
  return true if message.blank?
18
18
 
19
- message = format_message(severity, Time.now, progname, message)
20
- message = { message: message } unless message.is_a? Hash
19
+ message = format_message(severity, Time.zone.now, progname, message)
21
20
 
22
21
  @logger.post(@path, message)
23
22
  true
@@ -26,5 +25,16 @@ module FluentLoggerRails
26
25
  def close
27
26
  @logger.close
28
27
  end
28
+
29
+ delegate :add_tags, :remove_tags, :clear_tags!, to: :formatter
30
+
31
+ def tagged(*tags)
32
+ formatter.tagged(*tags) { yield self }
33
+ end
34
+
35
+ def flush
36
+ clear_tags!
37
+ super if defined?(super)
38
+ end
29
39
  end
30
40
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FluentLoggerRails
4
+ class TaggedHashFormatter < ::Logger::Formatter
5
+ # Parent key - ensures that if the log is being merged into a higher level payload this key can
6
+ # be set in order to not conflict or be overridden.
7
+ attr_accessor :parent_key
8
+
9
+ def initialize(merge_message_into_payload = false)
10
+ super()
11
+ @merge_message_into_payload = merge_message_into_payload
12
+ # Override the Logger::Formatter default to a format that does not have a trailing space
13
+ @datetime_format = "%Y-%m-%dT%H:%M:%S.%6N"
14
+ end
15
+
16
+ def call(severity, timestamp, _progname, msg)
17
+ payload = if msg.is_a?(Hash) && @merge_message_into_payload
18
+ msg
19
+ else
20
+ {
21
+ message: msg.is_a?(String) ? msg.strip : msg,
22
+ }
23
+ end
24
+
25
+ payload = payload.merge(
26
+ {
27
+ severity: format_severity(severity),
28
+ timestamp: format_datetime(timestamp),
29
+ },
30
+ ).merge(compact_tags.deep_dup)
31
+
32
+ @parent_key ? { @parent_key => payload } : payload
33
+ end
34
+
35
+ def format_severity(severity)
36
+ if severity.blank?
37
+ 'ANY'
38
+ elsif severity.is_a? Integer
39
+ ActiveSupport::Logger::SEV_LABEL[severity]
40
+ else
41
+ severity
42
+ end
43
+ end
44
+
45
+ def tagged(*tags)
46
+ add_tags(*tags)
47
+ yield self
48
+ ensure
49
+ remove_tags(*tags)
50
+ end
51
+
52
+ def add_tags(*tags)
53
+ tags = tags.first if tags.length == 1
54
+
55
+ if tags.is_a? Array
56
+ current_tags[:tags] ||= []
57
+ current_tags[:tags] += tags
58
+ elsif tags.is_a? String
59
+ current_tags[:tags] ||= []
60
+ current_tags[:tags] << tags
61
+ else
62
+ current_tags.merge! tags
63
+ end
64
+ end
65
+
66
+ def remove_tags(*tags)
67
+ tags = tags.first if tags.length == 1
68
+
69
+ if tags.is_a? Array
70
+ current_tags[:tags] ||= []
71
+ tags.each { |tag| current_tags[:tags].delete(tag) }
72
+ elsif tags.is_a? String
73
+ current_tags[:tags] ||= []
74
+ current_tags[:tags].delete(tags)
75
+ else
76
+ tags.each_key { |key| current_tags.delete(key) }
77
+ end
78
+ end
79
+
80
+ def clear_tags!
81
+ current_tags.clear
82
+ end
83
+
84
+ def current_tags
85
+ # We use our object ID here to avoid conflicting with other instances
86
+ thread_key = @thread_key ||= "fluent_logger_rails:#{object_id}"
87
+ Thread.current[thread_key] ||= {}
88
+ end
89
+
90
+ def compact_tags
91
+ current_tags.delete_if { |_k, v| v.blank? }
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module FluentLoggerRails
2
- VERSION = '0.1.0'
2
+ VERSION = '0.5.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent_logger_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HackerOne Open Source
@@ -15,16 +15,22 @@ dependencies:
15
15
  name: activesupport
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '5.0'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '7'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
- - - "~>"
28
+ - - ">="
26
29
  - !ruby/object:Gem::Version
27
30
  version: '5.0'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '7'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: rspec
30
36
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +73,10 @@ dependencies:
67
73
  - - ">="
68
74
  - !ruby/object:Gem::Version
69
75
  version: '0'
70
- description: A simple hello world gem
76
+ description: This is a library that wraps the [fluent-logger gem](https://github.com/fluent/fluent-logger-ruby)
77
+ and provides easy integration with your Rails application. This includes log formatters
78
+ that support [Rails tagged logging](https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html)
79
+ for JSON format that can be sent to Fluentd (or really any other logging backend).
71
80
  email:
72
81
  - opensource+fluent_logger_rails@hackerone.com
73
82
  - ben@hackeroen.com
@@ -75,6 +84,7 @@ executables: []
75
84
  extensions: []
76
85
  extra_rdoc_files: []
77
86
  files:
87
+ - ".github/workflows/ruby.yml"
78
88
  - ".gitignore"
79
89
  - ".rspec"
80
90
  - CHANGELOG.md
@@ -85,11 +95,8 @@ files:
85
95
  - README.md
86
96
  - fluent_logger_rails.gemspec
87
97
  - lib/fluent_logger_rails.rb
88
- - lib/fluent_logger_rails/hash_formatter.rb
89
- - lib/fluent_logger_rails/json_formatter.rb
90
98
  - lib/fluent_logger_rails/logger.rb
91
- - lib/fluent_logger_rails/pretty_json_formatter.rb
92
- - lib/fluent_logger_rails/tagged_logging.rb
99
+ - lib/fluent_logger_rails/tagged_hash_formatter.rb
93
100
  - lib/fluent_logger_rails/version.rb
94
101
  homepage: https://github.com/Hacker0x01/fluent_logger_rails
95
102
  licenses:
@@ -116,5 +123,5 @@ requirements: []
116
123
  rubygems_version: 3.0.3
117
124
  signing_key:
118
125
  specification_version: 4
119
- summary: A wrapper for fluent-logger gem to support tagged logging
126
+ summary: A wrapper for fluent-logger gem with support for tagged logging
120
127
  test_files: []
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class HashFormatter
4
- def call(severity, timestamp, _progname, msg)
5
- severity_display = if severity.blank?
6
- 'ANY'
7
- elsif severity.is_a? Integer
8
- ActiveSupport::Logger::SEV_LABEL[severity]
9
- else
10
- severity
11
- end
12
-
13
- {
14
- severity: severity_display,
15
- timestamp: timestamp.in_time_zone.strftime('%Y-%m-%d %H:%M:%S.%3N%z'),
16
- message: msg.is_a?(String) ? msg.strip : msg,
17
- }.merge(compact_tags)
18
- end
19
-
20
- def tagged(*tags)
21
- add_tags(*tags)
22
- yield self
23
- ensure
24
- remove_tags(*tags)
25
- end
26
-
27
- def add_tags(*tags)
28
- tags = tags.first if tags.length == 1
29
-
30
- if tags.is_a? Array
31
- current_tags[:tags] ||= []
32
- current_tags[:tags] += tags
33
- elsif tags.is_a? String
34
- current_tags[:tags] ||= []
35
- current_tags[:tags] << tags
36
- else
37
- current_tags.merge! tags
38
- end
39
- end
40
-
41
- def remove_tags(*tags)
42
- tags = tags.first if tags.length == 1
43
-
44
- if tags.is_a? Array
45
- current_tags[:tags] ||= []
46
- tags.each { |tag| current_tags[:tags].delete(tag) }
47
- elsif tags.is_a? String
48
- current_tags[:tags] ||= []
49
- current_tags[:tags].delete(tags)
50
- else
51
- tags.each_key { |key| current_tags.delete(key) }
52
- end
53
- end
54
-
55
- def clear_tags!
56
- current_tags.clear
57
- end
58
-
59
- def current_tags
60
- # We use our object ID here to avoid conflicting with other instances
61
- thread_key = @thread_key ||= "fluent_logger_rails:#{object_id}"
62
- Thread.current[thread_key] ||= {}
63
- end
64
-
65
- def compact_tags
66
- current_tags.delete_if { |_k, v| v.blank? }
67
- end
68
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class JsonFormatter < HashFormatter
4
- def call(severity, timestamp, progname, msg)
5
- super(severity, timestamp, progname, msg).to_json
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class PrettyJsonFormatter < HashFormatter
4
- def call(severity, timestamp, progname, msg)
5
- JSON.pretty_generate(super(severity, timestamp, progname, msg))
6
- end
7
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FluentLoggerRails
4
- module TaggedLogging
5
- def self.new(logger, format: :hash)
6
- logger.formatter = if format == :hash
7
- HashFormatter.new
8
- elsif format == :pretty_json
9
- PrettyJsonFormatter.new
10
- elsif format == :json
11
- JsonFormatter.new
12
- else
13
- fail "Unrecognized log format: '#{format}'"
14
- end
15
-
16
- logger.extend(self)
17
- end
18
-
19
- delegate :add_tags, :remove_tags, :clear_tags!, to: :formatter
20
-
21
- def tagged(*tags)
22
- formatter.tagged(*tags) { yield self }
23
- end
24
-
25
- def flush
26
- clear_tags!
27
- super if defined?(super)
28
- end
29
- end
30
- end