tablexi-logger 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24f5baa0ee4ada9002d1ede440013adf9700244e
4
+ data.tar.gz: 2ea1197b9a786f1a5f0b92cf75dea74493ff6b00
5
+ SHA512:
6
+ metadata.gz: 2828d849cb6f2b4c1822fe0c8bd5341ae7d90ef5c166d17bacd4713eec25aa2fbb2d2f37aea50f5af4b0271945d2bccea065d0ff8c56393f612a0389d0d8490e
7
+ data.tar.gz: 6a0d581fc5270ad173d52cf55b248a24415beebbc2bfdc433802ccb314aa740c91c624a6d723ee11275b87f0f33c881c869634e3c4ef6ad15ba173f3897b683f
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rubocop.yml ADDED
@@ -0,0 +1,39 @@
1
+ AllCops:
2
+ Exclude:
3
+ - ".bundle/**/*" # Auto-generated
4
+ - "bin/**/*" # Auto-generated
5
+ - "vendor/**/*" # We cannot solve the world's problems
6
+ - "tablexi-logger.gemspec" # just not worth it
7
+
8
+ Metrics/AbcSize:
9
+ Max: 25
10
+
11
+ Metrics/LineLength:
12
+ Max: 120
13
+
14
+ Metrics/MethodLength:
15
+ Max: 20
16
+
17
+ Style/Documentation:
18
+ Enabled: false
19
+
20
+ Style/EmptyLinesAroundBlockBody:
21
+ Enabled: false
22
+
23
+ Style/EmptyLinesAroundClassBody:
24
+ Enabled: false
25
+
26
+ Style/EmptyLinesAroundModuleBody:
27
+ Enabled: false
28
+
29
+ Style/SignalException:
30
+ EnforcedStyle: only_raise
31
+
32
+ Style/StringLiterals:
33
+ EnforcedStyle: double_quotes
34
+
35
+ Style/TrailingComma:
36
+ EnforcedStyleForMultiline: comma
37
+
38
+ Style/TrivialAccessors:
39
+ ExactNameMatch: true
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tablexi-logger.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Bradley Schaefer
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Tablexi::Logger
2
+
3
+ Standardized logging for Table XI applications.
4
+
5
+ The default behavior will log to `Rails.logger` or fallback to `::Logger.new($stdout)` if
6
+ Rails is not available. If [Rollbar](https://rollbar.com/) or [NewRelic](http://newrelic.com/)
7
+ are available, logging will also send events to the available service for log levels `error`
8
+ or higher.
9
+
10
+ ## Usage
11
+
12
+ Basic usage looks like this:
13
+
14
+ ```ruby
15
+ Tablexi.logger.warn "Missing configuration, using default"
16
+ Tablexi.logger.error "Bad Things Happened"
17
+ Tablexi.logger.error "Bad Request", request: request
18
+ Tablexi.logger.error "Request Timeout", metric: :timeout_error
19
+ ```
20
+
21
+ You may also assign the logger, for example configuring a null logger would look like this:
22
+
23
+ ```ruby
24
+ Tablexi.logger = ::Logger.new(File.open(File::NULL, "w"))
25
+ ```
26
+
27
+ ## Extending Functionality
28
+
29
+ ### Options Filtering
30
+
31
+ Applications may wish to modify the options passed to error handlers - for example
32
+ a `Tablexi::Logger::OptionFilter::HumanizeRequest` is provided by default, which
33
+ takes any `options[:request]` value and splits out the interesting parts such as
34
+ request method and body, and excludes the spammy parts such as headers.
35
+
36
+ Option filters may be configured via the `Tablexi::Logger#option_filters` array
37
+ with a callable:
38
+
39
+ ```ruby
40
+ Tablexi.logger.option_filters << ->(options) { options.delete(:password) }
41
+ ```
42
+
43
+ ### Registering logging handlers
44
+
45
+ Custom logging handlers implement callable and may be registered by log level (e.g. `:debug`):
46
+
47
+ ```ruby
48
+ Tablexi.logger.handlers[:debug] << ->(error, options) { puts [error, options].join("\n") }
49
+
50
+ # Or to register multiple severities at once
51
+ Tablexi.logger.handle [:debug, :warn, :info] do |*args|
52
+ puts args.join("\n")
53
+ end
54
+ ```
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ task :console do
9
+ require "irb"
10
+ require "irb/completion"
11
+ require "tablexi/logger"
12
+ ARGV.clear
13
+ IRB.start
14
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "tablexi/logger"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/circle.yml ADDED
@@ -0,0 +1,10 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.4
4
+ dependencies:
5
+ pre:
6
+ - gem install bundler --pre
7
+ test:
8
+ override:
9
+ - bundle exec rspec --order rand -fd --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec.xml:
10
+ parallel: true
@@ -0,0 +1,82 @@
1
+ require "logger"
2
+
3
+ require "tablexi/logger/version"
4
+ require "tablexi/logger/severities"
5
+ require "tablexi/logger/new_relic"
6
+ require "tablexi/logger/rollbar"
7
+ require "tablexi/logger/standard"
8
+ require "tablexi/logger/option_filter/humanize_request"
9
+
10
+ module Tablexi
11
+ class << self
12
+ attr_writer :logger
13
+
14
+ def logger
15
+ @logger ||= default_logger
16
+ end
17
+
18
+ def default_logger(base_logger = bare_logger)
19
+ Logger.new.tap do |logger|
20
+ logger.option_filters << Tablexi::Logger::OptionFilter::HumanizeRequest
21
+ Tablexi::Logger::SEVERITIES.each do |severity|
22
+ logger.handlers[severity] << Tablexi::Logger::Standard.new(base_logger, severity: severity)
23
+ end
24
+ trackable_severities = %i(error fatal unknown)
25
+ logger.handle trackable_severities, &Tablexi::Logger::Rollbar if defined?(::Rollbar)
26
+ logger.handle trackable_severities, &Tablexi::Logger::NewRelic if defined?(::NewRelic)
27
+ end
28
+ end
29
+
30
+ private def bare_logger
31
+ Rails.logger
32
+ rescue NameError
33
+ ::Logger.new($stdout).tap do |config|
34
+ config.level = ::Logger::DEBUG
35
+ end
36
+ end
37
+ end
38
+
39
+ class Logger
40
+ include Severities
41
+
42
+ attr_reader :option_filters
43
+ attr_reader :handlers
44
+
45
+ def initialize
46
+ @option_filters = []
47
+ @handlers = Hash.new { |h, k| h[k] = [] }
48
+ end
49
+
50
+ def handle(severities, &block)
51
+ raise ArgumentError, "Missing block argument" unless block_given?
52
+
53
+ Array(severities).each { |severity| handlers[severity] << block }
54
+ end
55
+
56
+ SEVERITIES.each do |severity|
57
+ define_method(severity) do |exception_or_message, options = {}|
58
+ log(severity, exception_or_message, Hash(options))
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def log(severity, exception_or_message, options)
65
+ process_option_filters(options)
66
+ handlers[severity].each do |handler|
67
+ handler.call(exception_or_message, options)
68
+ end
69
+ nil
70
+ rescue StandardError => e
71
+ if options.key? :tablexi_logger_error
72
+ raise # recursion prevention
73
+ else
74
+ error(e, tablexi_logger_error: true)
75
+ end
76
+ end
77
+
78
+ def process_option_filters(options)
79
+ option_filters.each_with_object(options) { |filter, opts| filter.call(opts) }
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,7 @@
1
+ module Tablexi
2
+ class Logger
3
+ NewRelic = lambda do |error, options|
4
+ ::NewRelic::Agent.notice_error(error, options)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ module Tablexi
2
+ class Logger
3
+ module OptionFilter
4
+ HumanizeRequest = lambda do |options|
5
+ return options unless options.key? :request
6
+
7
+ request = options.delete :request
8
+ body = request.body.read
9
+ request.body.rewind
10
+
11
+ options[:http_method] = request.headers["REQUEST_METHOD"]
12
+ options[:uri] = request.original_url
13
+ options[:body] = body
14
+ options
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ module Tablexi
2
+ class Logger
3
+ Rollbar = lambda do |error, options|
4
+ ::Rollbar.error(error, options)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ module Tablexi
2
+ class Logger
3
+ module Severities
4
+ SEVERITIES = %i(
5
+ debug
6
+ info
7
+ warn
8
+ error
9
+ fatal
10
+ unknown
11
+ ).freeze
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ require "tablexi/logger/severities"
2
+
3
+ module Tablexi
4
+ class Logger
5
+ class Standard
6
+ include Tablexi::Logger::Severities
7
+
8
+ attr_reader :logger
9
+ attr_reader :severity
10
+
11
+ def initialize(logger, severity: :unknown)
12
+ raise ArgumentError, "Severity `#{severity}` must be one of #{SEVERITIES}" unless SEVERITIES.include?(severity)
13
+
14
+ @logger = logger
15
+ @severity = severity
16
+ end
17
+
18
+ def call(exception_or_message, options)
19
+ logger.public_send severity, generate_log(exception_or_message, options)
20
+ end
21
+
22
+ private
23
+
24
+ def generate_log(exception_or_message, options)
25
+ options = Hash(options)
26
+
27
+ message = []
28
+ message << (exception_or_message.respond_to?(:message) ? exception_or_message.message : exception_or_message)
29
+ message << options.map { |k, v| "#{k}: #{v}" } if options.size > 0
30
+ message << exception_or_message.backtrace if exception_or_message.respond_to?(:backtrace)
31
+ message.flatten.join("\n")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module Tablexi
2
+ class Logger
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "tablexi/logger/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tablexi-logger"
8
+ spec.version = Tablexi::Logger::VERSION
9
+ spec.authors = ["Table XI Partners LLC", "Bradley Schaefer"]
10
+ spec.email = ["bradley.schaefer@gmail.com"]
11
+
12
+ spec.summary = "A simple logging wrapper to use in Table XI applications."
13
+ spec.description = "Provides a single interface for logging so that applications do not need to be aware of NewRelic, Rollbar, or whatever else."
14
+ spec.homepage = "https://github.com/tablexi/tablexi-logger"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.10"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.2"
25
+ spec.add_development_dependency "rspec_junit_formatter"
26
+ spec.add_development_dependency "rubocop"
27
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tablexi-logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Table XI Partners LLC
8
+ - Bradley Schaefer
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-09-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.10'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.10'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.2'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.2'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec_junit_formatter
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: Provides a single interface for logging so that applications do not need
85
+ to be aware of NewRelic, Rollbar, or whatever else.
86
+ email:
87
+ - bradley.schaefer@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rubocop.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - circle.yml
101
+ - lib/tablexi/logger.rb
102
+ - lib/tablexi/logger/new_relic.rb
103
+ - lib/tablexi/logger/option_filter/humanize_request.rb
104
+ - lib/tablexi/logger/rollbar.rb
105
+ - lib/tablexi/logger/severities.rb
106
+ - lib/tablexi/logger/standard.rb
107
+ - lib/tablexi/logger/version.rb
108
+ - tablexi-logger.gemspec
109
+ homepage: https://github.com/tablexi/tablexi-logger
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.6
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: A simple logging wrapper to use in Table XI applications.
133
+ test_files: []