simple_structured_logger 0.1.3 → 1.0.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
- SHA1:
3
- metadata.gz: 37a960d5ba5cba7d48661a92378a88278af39dfb
4
- data.tar.gz: 59d65009423e48bc513e640d859521fcf1e30cbe
2
+ SHA256:
3
+ metadata.gz: 824ec497606b6c639fdc7209c9854243512457bb7b97bc3ae3b6300354f85916
4
+ data.tar.gz: 56bdbf5858c33164a08ec88ee96cb0842c8f11a2caeef1123af14f3a2b0a73f7
5
5
  SHA512:
6
- metadata.gz: acdafee1c25ef8d234488ea38b10c93f436d4a2e860bff853ed02cc417b2c89ab22a8986e7ee1c1598a1ad1c4a36757d4aa081bd0b41d0370335d0aab334e7dd
7
- data.tar.gz: 8a9af6c2ce6b84b4e9e1c53ee1d22b710ad9caafa6d38de5c1c8991bdfbd094bfd34869f59e72520aa389ef06fbcecb9ed44fb5dac84223c6c79dcd930b18af7
6
+ metadata.gz: 8296498d2355f715ccc7a8b089f3129ed39688ebb8503e940f1b729d18d754142878524c48f3ab9cc8221910be0ea6200259ad9c1b1d4fa994f8e2dcab363ad2
7
+ data.tar.gz: 384a55748e300dcc7903be2609094af12fd88a4e2d3c58abf5646fb819314e9cb68b034c25890c2562355fe26babcd89fc422d617fd3373dff255ff0dc6b9ab9
@@ -0,0 +1,7 @@
1
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "bundler"
5
+ directory: "/" # Location of package manifests
6
+ schedule:
7
+ interval: "monthly"
@@ -0,0 +1,59 @@
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ # The branches below must be a subset of the branches above
8
+ branches: [ master ]
9
+ schedule:
10
+ - cron: '24 16 * * 1'
11
+
12
+ jobs:
13
+ analyze:
14
+ name: Analyze
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ actions: read
18
+ contents: read
19
+ security-events: write
20
+
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ language: [ 'ruby' ]
25
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
26
+ # Learn more about CodeQL language support at https://git.io/codeql-language-support
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v2
31
+
32
+ # Initializes the CodeQL tools for scanning.
33
+ - name: Initialize CodeQL
34
+ uses: github/codeql-action/init@v1
35
+ with:
36
+ languages: ${{ matrix.language }}
37
+ # If you wish to specify custom queries, you can do so here or in a config file.
38
+ # By default, queries listed here will override any specified in a config file.
39
+ # Prefix the list here with "+" to use these queries and those in the config file.
40
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
41
+
42
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
43
+ # If this step fails, then you should remove it and run the build manually (see below)
44
+ - name: Autobuild
45
+ uses: github/codeql-action/autobuild@v1
46
+
47
+ # ℹ️ Command-line programs to run using the OS shell.
48
+ # 📚 https://git.io/JvXDl
49
+
50
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
51
+ # and modify them (or add more) to build your code if your project
52
+ # uses a compiled language
53
+
54
+ #- run: |
55
+ # make bootstrap
56
+ # make release
57
+
58
+ - name: Perform CodeQL Analysis
59
+ uses: github/codeql-action/analyze@v1
@@ -0,0 +1,33 @@
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
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby-version }}
30
+ bundler-cache: true
31
+ - name: Run tests
32
+ run: bundle exec rake
33
+
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  /vendor/bundle
11
+ /*.gem
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.1.1
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
1
  source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in simple_structured_logger.gemspec
4
2
  gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Michael Bianco
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,22 +1,109 @@
1
+ [![Ruby](https://github.com/iloveitaly/simple_structured_logger/actions/workflows/ruby.yml/badge.svg)](https://github.com/iloveitaly/simple_structured_logger/actions/workflows/ruby.yml)
2
+ [![gem](https://img.shields.io/gem/v/simple_structured_logger.svg)](https://rubygems.org/gems/simple_structured_logger)
3
+
1
4
  # SimpleStructuredLogger
2
5
 
3
- Dead-simple structured logging in ruby with a dead-simple codebase. That's it.
6
+ Dead-simple structured logging in ruby with a dead-simple codebase. No dependencies, everything logs to stdout, and simple hooks to customize. That's it.
4
7
 
5
8
  ```ruby
6
9
  gem 'simple_structured_logger'
7
10
  ```
8
11
 
12
+ ## Usage
13
+
14
+ You can use this logger anywhere. Class methods, instance methods, use it as a logger for libraries, etc.
15
+
16
+ Some examples:
17
+
18
+ ```ruby
19
+ # in a console or simple script
20
+ include SimpleStructuredLogger
21
+ log.info 'core message', key: Time.now.to_i
22
+
23
+ # in class & instance methods
24
+ class LoggingInModule
25
+ include SimpleStructuredLogger
26
+
27
+ def self.log_something
28
+ log.info 'including the module enables a class and instance method', key: Time.now.to_i
29
+ end
30
+
31
+ def log_something_else
32
+ log.info 'the class and instance method share the same logging context', key: Time.now.to_i
33
+ end
34
+ end
35
+
36
+ # So, how do I set the context? How can I customize how it's set?
37
+ SimpleStructuredLogger.configure do
38
+ expand_context do |context|
39
+ # you can pass in a object and use `expand_context` to extract the relevant keys
40
+ if context[:user]
41
+ context[:user_id] = context[:user].id
42
+ context[:user_name] = context[:user].name
43
+ end
44
+
45
+ context
46
+ end
47
+ end
48
+
49
+ class ExampleJob
50
+ def perform(user_id)
51
+ user = get_user(user_id, job_argument)
52
+ log.set_context(user: user, job: self.class, job_argument: job_argument)
53
+ log.info 'the log will contain the user_id, job_argument, and job class'
54
+
55
+ # you can also add additional default pairs without resetting context
56
+ log.default_tags[:something] = 'else'
57
+ end
58
+ end
59
+
60
+ # Can you pass object arguments as values and automatically expand them? Well, yes, you can!
61
+ SimpleStructuredLogger.configure do
62
+ expand_log do |tags, default_tags|
63
+ if tags[:stripe_resource] && tags[:stripe_resource].respond_to?(:id)
64
+ stripe_resource = tags.delete(:stripe_resource)
65
+ tags[:stripe_resource_id] = stripe_resource.id
66
+ tags[:stripe_resource_type] = stripe_resource.class.to_s
67
+ end
68
+
69
+ # this is a really nice pattern I like to use. The `metric` key can trigger a call out to your observability tooling
70
+ if tags[:metric]
71
+ dimensions = default_tags.slice(:stripe_user_id, :other_default_tag)
72
+ metrics.track_counter(tags[:metric], dimensions: dimensions)
73
+ end
74
+
75
+ tags
76
+ end
77
+ end
78
+
79
+ # want simple formatting? You got it!
80
+ SimpleStructuredLogger.logger.formatter = proc do |severity, _datetime, _progname, msg|
81
+ "#{severity}: #{msg}\n"
82
+ end
83
+
84
+ # Configure the logger directly if you need to
85
+ SimpleStructuredLogger.logger.level(Logger::INFO)
86
+ ```
87
+
88
+ Want to change the log level quickly? Without modifying source?
89
+
90
+ ```shell
91
+ LOG_LEVEL=DEBUG ruby your_script.rb
92
+
93
+ # case does not matter
94
+ LOG_LEVEL=info ruby your_script.rb
95
+ ```
96
+
9
97
  ## Design Goals
10
98
 
11
99
  * Extremely simple codebase that's easy to read and override
12
- * Structured logging that reads nicely
100
+ * Structured logging that reads nicely and is easy to filter using grep or something like Papertrail
13
101
  * Ability to easily set context, and expand context with user-configurable hook
14
102
  * Ability to easily add structured log pre-processing. I want to be able to pass
15
- in an object specific to my application and for the relavent important keys to
103
+ in an object specific to my application and for the relevant important keys to
16
104
  be expanded automatically.
17
105
  * `Rails.logger = SimpleStructuredLogger.new(STDOUT)`
18
- * Not designed around massive systems or scale
19
- * Don't support multiple log destinations
106
+ * Not designed around massive systems or scale: no JSON logging, multiple log destinations, and other fanciness.
20
107
  * Don't build in fancy pre-processing for errors or other common ruby objects
21
108
 
22
109
  ### Opinionated Devops Setup
@@ -32,6 +119,11 @@ gem 'simple_structured_logger'
32
119
  * https://github.com/asenchi/scrolls
33
120
  * https://github.com/stripe/chalk-log
34
121
  * https://github.com/nishidayuya/structured_logger
122
+ * https://github.com/rocketjob/semantic_logger
123
+
124
+ ## Related
125
+
126
+ * https://github.com/roidrage/lograge
35
127
 
36
128
  ## Why is structured logging important?
37
129
 
@@ -41,14 +133,14 @@ gem 'simple_structured_logger'
41
133
  ## What about Rail's tagged logging?
42
134
 
43
135
  Tagged logging is not structured logging. I want to be able to search through
44
- PaperTrail and easily grab an audit trail for a specific context, i.e. `the_job=FailingJob the_user=1`.
45
-
46
- ## Usage
47
-
48
- TODO: Write usage instructions here
136
+ PaperTrail/Splunk/etc and easily grab an audit trail for a specific context, i.e. `the_job=FailingJob the_user=1`.
49
137
 
50
138
  ## Testing
51
139
 
52
140
  ```
53
141
  bundle exec rake
54
142
  ```
143
+
144
+ ## TODO
145
+
146
+ - [ ] Support logs as blocks?
@@ -2,6 +2,14 @@ require 'logger'
2
2
  require 'singleton'
3
3
 
4
4
  module SimpleStructuredLogger
5
+ def self.configure(&block)
6
+ SimpleStructuredLogger::Configuration.instance_eval(&block)
7
+ end
8
+
9
+ def self.logger
10
+ SimpleStructuredLogger::Writer.instance.logger
11
+ end
12
+
5
13
  def log
6
14
  SimpleStructuredLogger::Writer.instance
7
15
  end
@@ -13,25 +21,27 @@ module SimpleStructuredLogger
13
21
  SimpleStructuredLogger::Writer.instance
14
22
  end
15
23
  end
16
-
17
24
  end
18
25
 
19
26
  module Configuration
20
27
  extend self
21
28
 
29
+ @expand_context = nil
30
+ @expand_log = nil
31
+
22
32
  def expand_context(&block)
23
33
  if block.nil?
24
- @expand_context = block
25
- else
26
34
  @expand_context
35
+ else
36
+ @expand_context = block
27
37
  end
28
38
  end
29
39
 
30
40
  def expand_log(&block)
31
41
  if block.nil?
32
- @expand_log = block
33
- else
34
42
  @expand_log
43
+ else
44
+ @expand_log = block
35
45
  end
36
46
  end
37
47
  end
@@ -39,11 +49,21 @@ module SimpleStructuredLogger
39
49
  class Writer
40
50
  include Singleton
41
51
 
42
- attr_reader :default_tags, :logger
52
+ attr_accessor :default_tags, :logger
43
53
 
44
54
  def initialize
45
55
  @logger = ::Logger.new(STDOUT)
46
56
  @default_tags = {}
57
+
58
+ set_log_level_from_environment
59
+ end
60
+
61
+ def set_log_level_from_environment
62
+ env_log_level = ENV['LOG_LEVEL']
63
+
64
+ if !env_log_level.nil? && Logger::Severity.const_defined?(env_log_level.upcase)
65
+ @logger.level = Logger::Severity.const_get(env_log_level.upcase)
66
+ end
47
67
  end
48
68
 
49
69
  def reset_context!
@@ -53,8 +73,8 @@ module SimpleStructuredLogger
53
73
  def set_context(context)
54
74
  reset_context!
55
75
 
56
- if self.respond_to?(:expand_context)
57
- context = self.expand_context(context)
76
+ if SimpleStructuredLogger::Configuration.expand_context
77
+ context = SimpleStructuredLogger::Configuration.expand_context.call(context)
58
78
  end
59
79
 
60
80
  @default_tags.merge!(context)
@@ -76,17 +96,15 @@ module SimpleStructuredLogger
76
96
  @logger.warn("#{msg}: #{stringify_tags(opts)}")
77
97
  end
78
98
 
79
- private
80
-
81
- def stringify_tags(additional_tags)
82
- additional_tags = additional_tags.dup
83
-
84
- if self.respond_to?(:expand_log)
85
- additional_tags = self.expand_log(additional_tags)
86
- end
99
+ private def stringify_tags(additional_tags)
100
+ additional_tags = additional_tags.dup
87
101
 
88
- @default_tags.merge(additional_tags).map { |k,v| "#{k}=#{v}" }.join(' ')
102
+ if SimpleStructuredLogger::Configuration.expand_log
103
+ additional_tags = SimpleStructuredLogger::Configuration.expand_log.call(additional_tags, self.default_tags)
89
104
  end
90
105
 
106
+ @default_tags.merge(additional_tags).map {|k, v| "#{k}=#{v}" }.join(' ')
107
+ end
108
+
91
109
  end
92
110
  end
@@ -4,20 +4,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "simple_structured_logger"
7
- spec.version = '0.1.3'
7
+ spec.version = '1.0.0'
8
8
  spec.authors = ["Michael Bianco"]
9
- spec.email = ["mike@cliffsidemedia.com"]
9
+ spec.email = ["mike@mikebian.co"]
10
+ spec.licenses = ['MIT']
10
11
 
11
- spec.summary = "Dead-simple structured logging in ruby with a dead-simple codebase."
12
- # spec.description = %q{TODO: Write a longer description or delete this line.}
12
+ spec.summary = "Dead-simple structured logging in ruby with a simple codebase"
13
13
  spec.homepage = "https://github.com/iloveitaly/simple_structured_logger"
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
17
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
17
  spec.require_paths = ["lib"]
19
18
 
20
- spec.add_development_dependency "bundler", "~> 1.11"
21
- spec.add_development_dependency "rake", "~> 10.0"
22
- spec.add_development_dependency "minitest", "~> 5.0"
19
+ spec.add_development_dependency "bundler", "~> 2.3.10"
20
+ spec.add_development_dependency "rake", "~> 13.0.6"
21
+ spec.add_development_dependency "minitest", "~> 5.15"
23
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_structured_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bianco
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-27 00:00:00.000000000 Z
11
+ date: 2022-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,51 +16,58 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: 2.3.10
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: 2.3.10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 13.0.6
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 13.0.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '5.0'
47
+ version: '5.15'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '5.0'
55
- description:
54
+ version: '5.15'
55
+ description:
56
56
  email:
57
- - mike@cliffsidemedia.com
58
- executables: []
57
+ - mike@mikebian.co
58
+ executables:
59
+ - console
60
+ - setup
59
61
  extensions: []
60
62
  extra_rdoc_files: []
61
63
  files:
64
+ - ".github/dependabot.yml"
65
+ - ".github/workflows/codeql-analysis.yml"
66
+ - ".github/workflows/ruby.yml"
62
67
  - ".gitignore"
68
+ - ".tool-versions"
63
69
  - Gemfile
70
+ - LICENSE
64
71
  - README.md
65
72
  - Rakefile
66
73
  - bin/console
@@ -68,9 +75,10 @@ files:
68
75
  - lib/simple_structured_logger.rb
69
76
  - simple_structured_logger.gemspec
70
77
  homepage: https://github.com/iloveitaly/simple_structured_logger
71
- licenses: []
78
+ licenses:
79
+ - MIT
72
80
  metadata: {}
73
- post_install_message:
81
+ post_install_message:
74
82
  rdoc_options: []
75
83
  require_paths:
76
84
  - lib
@@ -85,9 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
93
  - !ruby/object:Gem::Version
86
94
  version: '0'
87
95
  requirements: []
88
- rubyforge_project:
89
- rubygems_version: 2.6.4
90
- signing_key:
96
+ rubygems_version: 3.3.7
97
+ signing_key:
91
98
  specification_version: 4
92
- summary: Dead-simple structured logging in ruby with a dead-simple codebase.
99
+ summary: Dead-simple structured logging in ruby with a simple codebase
93
100
  test_files: []