macmillan-utils 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.hound.yml +36 -0
- data/.rspec +3 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +113 -0
- data/Rakefile +12 -0
- data/lib/macmillan/utils.rb +16 -0
- data/lib/macmillan/utils/bundler/gem_helper.rb +9 -0
- data/lib/macmillan/utils/cucumber/cucumber_defaults.rb +12 -0
- data/lib/macmillan/utils/cucumber/webmock_helper.rb +9 -0
- data/lib/macmillan/utils/logger.rb +11 -0
- data/lib/macmillan/utils/logger/factory.rb +77 -0
- data/lib/macmillan/utils/logger/formatter.rb +48 -0
- data/lib/macmillan/utils/middleware.rb +7 -0
- data/lib/macmillan/utils/middleware/weak_etags.rb +33 -0
- data/lib/macmillan/utils/rails/statsd_instrumentation.rb +64 -0
- data/lib/macmillan/utils/rspec/rack_test_helper.rb +12 -0
- data/lib/macmillan/utils/rspec/rspec_defaults.rb +44 -0
- data/lib/macmillan/utils/rspec/webmock_helper.rb +13 -0
- data/lib/macmillan/utils/settings.rb +33 -0
- data/lib/macmillan/utils/settings/app_yaml_backend.rb +44 -0
- data/lib/macmillan/utils/settings/env_vars_backend.rb +13 -0
- data/lib/macmillan/utils/settings/key_not_found.rb +13 -0
- data/lib/macmillan/utils/settings/lookup.rb +29 -0
- data/lib/macmillan/utils/settings/value.rb +16 -0
- data/lib/macmillan/utils/statsd_controller_helper.rb +81 -0
- data/lib/macmillan/utils/statsd_decorator.rb +98 -0
- data/lib/macmillan/utils/statsd_middleware.rb +87 -0
- data/lib/macmillan/utils/statsd_stub.rb +43 -0
- data/lib/macmillan/utils/test_helpers/codeclimate_helper.rb +4 -0
- data/lib/macmillan/utils/test_helpers/fixture_loading_helper.rb +24 -0
- data/lib/macmillan/utils/test_helpers/simplecov_helper.rb +27 -0
- data/macmillan-utils.gemspec +33 -0
- data/spec/fixtures/config/application.yml +1 -0
- data/spec/lib/macmillan/utils/logger/factory_spec.rb +53 -0
- data/spec/lib/macmillan/utils/logger/formatter_spec.rb +57 -0
- data/spec/lib/macmillan/utils/middleware/weak_etags_spec.rb +30 -0
- data/spec/lib/macmillan/utils/settings_spec.rb +44 -0
- data/spec/lib/macmillan/utils/statsd_controller_helper_spec.rb +43 -0
- data/spec/lib/macmillan/utils/statsd_decorator_spec.rb +93 -0
- data/spec/lib/macmillan/utils/statsd_middleware_spec.rb +51 -0
- data/spec/spec_helper.rb +13 -0
- metadata +296 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 618626d3f23f078df01d4ff82448a7fbb61510c2
|
4
|
+
data.tar.gz: 6849bec7f310b4e0b94882f5ce30385bd7ce0dcb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bbc3d8a092c4eec621516f0280646d185451a2ce3caec1a1ba5833d51e9309ce66767c71001d7f0e4d4a25260d62ed36c557136164572ed6b1c910ab8456a6ac
|
7
|
+
data.tar.gz: e294f634ff213e82c1c400176d02255ac8b08a541a709b375293aeb61f8ef202d8f8fa0c2c108413cd7a2c68c6b5d01c1928fe007c8ef5fa224424d490f94410
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
InstalledFiles
|
7
|
+
_yardoc
|
8
|
+
coverage
|
9
|
+
doc/
|
10
|
+
lib/bundler/man
|
11
|
+
pkg
|
12
|
+
rdoc
|
13
|
+
spec/reports
|
14
|
+
test/tmp
|
15
|
+
test/version_tmp
|
16
|
+
tmp
|
17
|
+
*.bundle
|
18
|
+
*.so
|
19
|
+
*.o
|
20
|
+
*.a
|
21
|
+
mkmf.log
|
22
|
+
RBENV_VERSION*
|
23
|
+
Gemfile.lock
|
data/.hound.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
Metrics/LineLength:
|
2
|
+
Description: 'Limit lines to 120 characters.'
|
3
|
+
Max: 120
|
4
|
+
|
5
|
+
Style/Documentation:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Style/SingleSpaceBeforeFirstArg:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/BracesAroundHashParameters:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/IndentHash:
|
15
|
+
EnforcedStyle: consistent
|
16
|
+
|
17
|
+
Style/AlignHash:
|
18
|
+
EnforcedHashRocketStyle: table
|
19
|
+
EnforcedColonStyle: table
|
20
|
+
|
21
|
+
Style/AlignParameters:
|
22
|
+
EnforcedStyle: with_fixed_indentation
|
23
|
+
|
24
|
+
Style/StringLiterals:
|
25
|
+
EnforcedStyle: single_quotes
|
26
|
+
|
27
|
+
Style/CollectionMethods:
|
28
|
+
PreferredMethods:
|
29
|
+
collect: 'map'
|
30
|
+
collect!: 'map!'
|
31
|
+
inject: 'reduce'
|
32
|
+
detect: 'find'
|
33
|
+
find_all: 'select'
|
34
|
+
|
35
|
+
Style/DotPosition:
|
36
|
+
EnforcedStyle: leading
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
Metrics/LineLength:
|
2
|
+
Description: 'Limit lines to 120 characters.'
|
3
|
+
Max: 120
|
4
|
+
|
5
|
+
Style/Documentation:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Style/SingleSpaceBeforeFirstArg:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/BracesAroundHashParameters:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/IndentHash:
|
15
|
+
EnforcedStyle: consistent
|
16
|
+
|
17
|
+
Style/AlignHash:
|
18
|
+
EnforcedHashRocketStyle: table
|
19
|
+
EnforcedColonStyle: table
|
20
|
+
|
21
|
+
Style/AlignParameters:
|
22
|
+
EnforcedStyle: with_fixed_indentation
|
23
|
+
|
24
|
+
Style/StringLiterals:
|
25
|
+
EnforcedStyle: single_quotes
|
26
|
+
|
27
|
+
Style/CollectionMethods:
|
28
|
+
PreferredMethods:
|
29
|
+
collect: 'map'
|
30
|
+
collect!: 'map!'
|
31
|
+
inject: 'reduce'
|
32
|
+
detect: 'find'
|
33
|
+
find_all: 'select'
|
34
|
+
|
35
|
+
Style/DotPosition:
|
36
|
+
EnforcedStyle: leading
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
- 2.1.0
|
7
|
+
- 2.1.1
|
8
|
+
- 2.1.2
|
9
|
+
- 2.1.3
|
10
|
+
- 2.1.4
|
11
|
+
- 2.1.5
|
12
|
+
- 2.2.0
|
13
|
+
- jruby-19mode
|
14
|
+
env:
|
15
|
+
- USE_SIMPLECOV=true CODECLIMATE_REPO_TOKEN=2175628fb41494d45b50b6938600a53c130e1f7ac3b81b072bb71e91073a5e4a
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Macmillan Science and Education
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
= Macmillan::Utils
|
2
|
+
|
3
|
+
A collection of useful patterns we use in our Ruby applications.
|
4
|
+
|
5
|
+
{<img src="https://travis-ci.org/nature/macmillan-utils.svg?branch=log-formatter" alt="Build Status" />}[https://travis-ci.org/nature/macmillan-utils]
|
6
|
+
{<img src="https://codeclimate.com/github/nature/macmillan-utils.png" alt="CodeClimate Rating" />}[https://codeclimate.com/github/nature/macmillan-utils]
|
7
|
+
{<img src="https://codeclimate.com/github/nature/macmillan-utils/coverage.png" alt="Test Coverage" />}[https://codeclimate.com/github/nature/macmillan-utils]
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'macmillan-utils', require: false
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself with:
|
20
|
+
|
21
|
+
$ gem install macmillan-utils
|
22
|
+
|
23
|
+
== Usage
|
24
|
+
|
25
|
+
=== Logger Objects
|
26
|
+
|
27
|
+
To build logger objects quickly and easily:
|
28
|
+
|
29
|
+
require 'macmillan/utils/logger'
|
30
|
+
|
31
|
+
logger = Macmillan::Utils::Logger::Factory.build_logger(:syslog, tag: 'myapp')
|
32
|
+
|
33
|
+
The logger will automatically use the {Macmillan::Utils::Logger::Formatter} formatter, and will log at the
|
34
|
+
{Logger::INFO} level.
|
35
|
+
|
36
|
+
See the class documentation for more information:
|
37
|
+
|
38
|
+
* {Macmillan::Utils::Logger::Factory}
|
39
|
+
* {Macmillan::Utils::Logger::Formatter}
|
40
|
+
|
41
|
+
=== Settings
|
42
|
+
|
43
|
+
Easily store and lookup configuration values in either environment variables, or a `application.yml` file.
|
44
|
+
|
45
|
+
ENV['REDIS_URL'] = 'localhost'
|
46
|
+
$settings = Macmillan::Utils::Settings.instance
|
47
|
+
redis_url = $settings.lookup('redis_url') #=> 'localhost'
|
48
|
+
|
49
|
+
The default action is to support BOTH environment variables and a `application.yml` file for settings - if you would
|
50
|
+
prefer only one or the other, see the 'Switching Backends' section.
|
51
|
+
|
52
|
+
If a setting is requested and it has not been set (in any configured backend), a Macmillan::Utils::Settings::KeyNotFoundError
|
53
|
+
is raised.
|
54
|
+
|
55
|
+
==== Evironment Variables
|
56
|
+
|
57
|
+
Set your environment variables as you would normally, using all caps for the key name, and you can then fetch the value
|
58
|
+
using `.lookup`. Simples.
|
59
|
+
|
60
|
+
==== `application.yml` Files
|
61
|
+
|
62
|
+
If you prefer to use a YAML based config file, this is the option for you. The code will first look for a `application.yml`
|
63
|
+
file in a `config` directory (within the current working directory), if it doesn't find one, then it looks in the current
|
64
|
+
working directory, and keeps moving up the filesystem until it finds one. If it doesn't it raises an error.
|
65
|
+
|
66
|
+
==== Switching Backends
|
67
|
+
|
68
|
+
By default both the environment variable and application yaml backends are used, if you'd like only one, you need to specify this
|
69
|
+
before building the settings instance, i.e.:
|
70
|
+
|
71
|
+
Macmillan::Utils::Settings.backends = [Macmillan::Utils::Settings::EnvVarsBackend]
|
72
|
+
|
73
|
+
would only look for environment variables, whereas
|
74
|
+
|
75
|
+
Macmillan::Utils::Settings.backends = [Macmillan::Utils::Settings::AppYamlBackendBackend]
|
76
|
+
|
77
|
+
would only look for settings in an `application.yml` file.
|
78
|
+
|
79
|
+
=== RSpec Helpers
|
80
|
+
|
81
|
+
Add the following to the top of your `spec_helper.rb`:
|
82
|
+
|
83
|
+
require 'macmillan/utils/rspec/rspec_defaults'
|
84
|
+
require 'macmillan/utils/rspec/webmock_helper'
|
85
|
+
require 'macmillan/utils/test_helpers/codeclimate_helper'
|
86
|
+
require 'macmillan/utils/test_helpers/simplecov_helper'
|
87
|
+
require 'macmillan/utils/test_helpers/fixture_loading_helper'
|
88
|
+
|
89
|
+
=== Cucumber Helpers
|
90
|
+
|
91
|
+
Add the following to the top of your `env.rb`:
|
92
|
+
|
93
|
+
require 'macmillan/utils/cucumber/cucumber_defaults'
|
94
|
+
require 'macmillan/utils/cucumber/webmock_helper'
|
95
|
+
require 'macmillan/utils/test_helpers/codeclimate_helper'
|
96
|
+
require 'macmillan/utils/test_helpers/simplecov_helper'
|
97
|
+
require 'macmillan/utils/test_helpers/fixture_loading_helper'
|
98
|
+
|
99
|
+
=== StatsD
|
100
|
+
|
101
|
+
* {Macmillan::Utils::StatsdDecorator} - Logging and more for StatsD calls.
|
102
|
+
* {Macmillan::Utils::StatsdStub} - Stubbed StatsD class for use in test suites.
|
103
|
+
* {Macmillan::Utils::StatsdMiddleware} - Rack middleware for sending web application metrics to StatsD
|
104
|
+
* {Macmillan::Utils::StatsdControllerHelper} - Helper functions to send metrics to StatsD via {Macmillan::Utils::StatsdMiddleware}
|
105
|
+
|
106
|
+
== Contributing
|
107
|
+
|
108
|
+
1. Fork it ( https://github.com/nature/macmillan-utils/fork )
|
109
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
110
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
111
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
112
|
+
5. Create a new Pull Request
|
113
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
##
|
2
|
+
# Namespace for Macmillan code...
|
3
|
+
#
|
4
|
+
module Macmillan
|
5
|
+
##
|
6
|
+
# Utils module for use in Macmillan applications
|
7
|
+
#
|
8
|
+
module Utils
|
9
|
+
autoload :Logger, 'macmillan/utils/logger'
|
10
|
+
autoload :Middleware, 'macmillan/utils/middleware'
|
11
|
+
autoload :Settings, 'macmillan/utils/settings'
|
12
|
+
autoload :StatsdDecorator, 'macmillan/utils/statsd_decorator'
|
13
|
+
autoload :StatsdMiddleware, 'macmillan/utils/statsd_middleware'
|
14
|
+
autoload :StatsdControllerHelper, 'macmillan/utils/statsd_controller_helper'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'cucumber'
|
2
|
+
require 'multi_test'
|
3
|
+
|
4
|
+
# control rogue test/unit/autorun requires
|
5
|
+
MultiTest.disable_autorun
|
6
|
+
|
7
|
+
# exit the suite after the first failure
|
8
|
+
if ENV['FAIL_FAST']
|
9
|
+
After do |scenario|
|
10
|
+
Cucumber.wants_to_quit = true if scenario.failed?
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require_relative 'formatter'
|
3
|
+
|
4
|
+
module Macmillan
|
5
|
+
module Utils
|
6
|
+
module Logger
|
7
|
+
##
|
8
|
+
# A factory class for building logger objects
|
9
|
+
#
|
10
|
+
# === Usage:
|
11
|
+
#
|
12
|
+
# require 'macmillan/utils/logger'
|
13
|
+
#
|
14
|
+
# Macmillan::Utils::Logger::Factory.build_logger(type, options)
|
15
|
+
#
|
16
|
+
class Factory
|
17
|
+
##
|
18
|
+
# Builds a logger object
|
19
|
+
#
|
20
|
+
# Opts varies depending on the type of logger object you are creating:
|
21
|
+
#
|
22
|
+
# opts for :syslog
|
23
|
+
# :tag => [String] the name of the syslog tag to use
|
24
|
+
# :facility => [Integer] the 'LOG_LOCALx' syslog facility to use
|
25
|
+
#
|
26
|
+
# opts for :logger
|
27
|
+
# :target => [String, Object] the target for the Logger object
|
28
|
+
#
|
29
|
+
# opts for :null
|
30
|
+
# none
|
31
|
+
#
|
32
|
+
# @param type [Symbol] the logger type, `:logger`, `:syslog` or `:null`
|
33
|
+
# @param opts [Hash] options to pass to your logger object
|
34
|
+
# @return [Logger] the configured logger object
|
35
|
+
#
|
36
|
+
def self.build_logger(type = :logger, opts = {})
|
37
|
+
logger = case type
|
38
|
+
when :syslog then build_syslog_logger(opts)
|
39
|
+
when :null then build_normal_logger(target: '/dev/null')
|
40
|
+
else
|
41
|
+
build_normal_logger(opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
logger.formatter = ::Macmillan::Utils::Logger::Formatter.new
|
45
|
+
logger.level = ::Logger::INFO
|
46
|
+
|
47
|
+
logger
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.build_syslog_logger(opts)
|
51
|
+
require 'syslog-logger'
|
52
|
+
|
53
|
+
::Logger::Syslog.class_eval do
|
54
|
+
alias_method :write, :info
|
55
|
+
alias_method :log, :info
|
56
|
+
end
|
57
|
+
|
58
|
+
tag = opts.fetch(:tag)
|
59
|
+
facility = Syslog.const_get("LOG_LOCAL#{opts.fetch(:facility, 0)}")
|
60
|
+
|
61
|
+
::Logger::Syslog.new(tag, facility)
|
62
|
+
end
|
63
|
+
private_class_method :build_syslog_logger
|
64
|
+
|
65
|
+
def self.build_normal_logger(opts)
|
66
|
+
::Logger.class_eval do
|
67
|
+
alias_method :write, :info
|
68
|
+
alias_method :log, :info
|
69
|
+
end
|
70
|
+
|
71
|
+
::Logger.new(opts.fetch(:target, $stdout))
|
72
|
+
end
|
73
|
+
private_class_method :build_normal_logger
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Macmillan
|
2
|
+
module Utils
|
3
|
+
module Logger
|
4
|
+
##
|
5
|
+
# A log formatter class for Logger objects. This formatter is used automatically
|
6
|
+
# when you use the {Macmillan::Utils::Logger::Factory} class.
|
7
|
+
#
|
8
|
+
# === Usage:
|
9
|
+
#
|
10
|
+
# require 'macmillan/utils/logger'
|
11
|
+
#
|
12
|
+
# logger = Macmillan::Utils::Logger::Factory.build_logger(type, options)
|
13
|
+
#
|
14
|
+
class Formatter < ::Logger::Formatter
|
15
|
+
##
|
16
|
+
# Builds a new instance of Formatter
|
17
|
+
#
|
18
|
+
# @param prefix [String] a string to prepend to all log lines
|
19
|
+
# @return [Formatter] the configured formatter object
|
20
|
+
#
|
21
|
+
def initialize(prefix = nil)
|
22
|
+
@format = "[%5s]: %s\n"
|
23
|
+
@format = "#{prefix} #{@format}" if prefix
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Returns the log message formatted as desired
|
28
|
+
#
|
29
|
+
def call(severity, _time, _progname, msg)
|
30
|
+
@format % [severity, msg2str(msg)]
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def msg2str(msg)
|
36
|
+
case msg
|
37
|
+
when ::String
|
38
|
+
msg
|
39
|
+
when ::Exception
|
40
|
+
"#{ msg.message } (#{ msg.class })\n" << (msg.backtrace || []).join("\n")
|
41
|
+
else
|
42
|
+
msg.inspect
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|