diff --git a/.rubocop.yml b/.rubocop.yml index 2db517c..86b6a53 100755 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,66 +2,77 @@ inherit_from: #{RUBOCOP_HOME}/config/default.yml AllCops: - TargetRubyVersion: 2.4 + SuggestExtensions: false + TargetRubyVersion: 2.7 Exclude: - 'vendor/**/*' - 'Guardfile' + NewCops: enable -CyclomaticComplexity: - Max: 15 - -PerceivedComplexity: - Max: 20 - -MethodLength: - Max: 30 +Gemspec/RequireMFA: + Enabled: false -ClassLength: +Layout/LeadingCommentSpace: Enabled: false -LineLength: +Layout/LineLength: Max: 150 -WordArray: +Layout/SpaceInsideHashLiteralBraces: + EnforcedStyle: no_space + +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' + +Metrics/BlockNesting: + Max: 4 + +Metrics/ClassLength: Enabled: false -LeadingCommentSpace: +Metrics/CyclomaticComplexity: + Max: 15 + +Metrics/MethodLength: + Max: 30 + +Metrics/PerceivedComplexity: + Max: 20 + +Style/AccessModifierDeclarations: + EnforcedStyle: inline + +Style/CommentAnnotation: Enabled: false -CommentAnnotation: +Style/Documentation: Enabled: false -Documentation: +Style/FrozenStringLiteralComment: Enabled: false -Next: +Style/HashConversion: + Enabled: true + +Style/Next: Enabled: false -OptionalArguments: +Style/OptionalArguments: Enabled: false -SpaceInsideHashLiteralBraces: - EnforcedStyle: no_space +Style/RedundantStringEscape: + Enabled: true -SignalException: +Style/SignalException: EnforcedStyle: only_raise -TrivialAccessors: - AllowPredicates: true - -BlockNesting: - Max: 4 - Style/StringLiterals: Enabled: true EnforcedStyle: single_quotes -Metrics/BlockLength: - Exclude: - - 'spec/**/*.rb' - -Style/FrozenStringLiteralComment: - Enabled: false +Style/TrivialAccessors: + AllowPredicates: true -Style/AccessModifierDeclarations: - EnforcedStyle: inline +Style/WordArray: + Enabled: false \ No newline at end of file diff --git a/.ruby-version b/.ruby-version index 6b4950e..1effb00 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4 +2.7 diff --git a/.travis.yml b/.travis.yml index 7ba418e..022fd3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: ruby cache: bundler -rvm: 2.4 +rvm: 2.7 before_install: - gem update --system - gem install bundler diff --git a/bin/profile b/bin/profile index 1a27466..52e12ed 100755 --- a/bin/profile +++ b/bin/profile @@ -17,4 +17,4 @@ result.eliminate_methods!([/Integer#times/]) # printer = RubyProf::GraphPrinter.new(result) printer = RubyProf::FlatPrinterWithLineNumbers.new(result) -printer.print(STDOUT) +printer.print($stdout) diff --git a/hedgelog.gemspec b/hedgelog.gemspec index 985332f..fe4a56a 100644 --- a/hedgelog.gemspec +++ b/hedgelog.gemspec @@ -5,12 +5,13 @@ require 'hedgelog/version' Gem::Specification.new do |spec| spec.name = 'hedgelog' spec.version = Hedgelog::VERSION + spec.required_ruby_version = '>= 2.7.0' spec.licenses = ['MIT'] - spec.authors = ['Jeff Utter'] - spec.email = ['jeff.utter@firespring.com'] + spec.authors = ['Firespring'] + spec.email = ['opensource@firespring.com'] spec.homepage = 'https://github.com/firespring/hedgelog' - spec.summary = 'A strucutred JSON logger for Ruby' + spec.summary = 'A structured JSON logger for Ruby' spec.description = 'An opinionated/structured JSON logger for Ruby' spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } @@ -18,6 +19,5 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'yajl-ruby', '~> 1.4' spec.add_development_dependency 'bundler' end diff --git a/lib/hedgelog.rb b/lib/hedgelog.rb index 6a5074c..f813304 100755 --- a/lib/hedgelog.rb +++ b/lib/hedgelog.rb @@ -5,7 +5,7 @@ require 'hedgelog/scrubber' require 'hedgelog/normalizer' require 'logger' -require 'yajl' +require 'json' class Hedgelog LEVELS = %w[DEBUG INFO WARN ERROR FATAL UNKNOWN].each_with_object({}).with_index do |(v, h), i| @@ -25,7 +25,8 @@ class Hedgelog attr_reader :level attr_writer :app - def initialize(logdev = STDOUT, shift_age = nil, shift_size = nil, cleaner = nil) + # rubocop:disable Metrics/ParameterLists + def initialize(logdev = $stdout, shift_age = nil, shift_size = nil, cleaner = nil) @level = LEVELS[:debug] @channel = nil @logdev = nil @@ -40,6 +41,7 @@ def initialize(logdev = STDOUT, shift_age = nil, shift_size = nil, cleaner = nil @logdev = Logger::LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size) end end + # rubocop:enable Metrics/ParameterLists def level=(level) int_level = level_to_int(level) @@ -48,6 +50,7 @@ def level=(level) @level = int_level end + # rubocop:disable Metrics/ParameterLists def add(severity = LEVELS[:unknown], message = nil, progname = nil, context = {}, &block) return true if (@logdev.nil? && @channel.nil?) || severity < @level @@ -62,6 +65,7 @@ def add(severity = LEVELS[:unknown], message = nil, progname = nil, context = {} @channel&.add(severity, nil, progname, context) end + # rubocop:enable Metrics/ParameterLists def []=(key, val) @channel_context[key] = val @@ -147,7 +151,7 @@ def formatter=(_value) data[:caller] = debugharder(caller(4, 1).first) if debug? data = extract_top_level_keys(data) - @logdev.write(Yajl::Encoder.encode(data) + "\n") + @logdev.write("#{JSON.generate(data)}\n") true end @@ -176,7 +180,7 @@ def formatter=(_value) whence = $LOAD_PATH.find { |p| path.start_with?(p) } file = if whence # Remove the RUBYLIB path portion of the full file name - path[whence.length + 1..-1] + path[whence.length + 1..] else # We get here if the path is not in $: path diff --git a/lib/hedgelog/normalizer.rb b/lib/hedgelog/normalizer.rb index 3963c36..b31e654 100644 --- a/lib/hedgelog/normalizer.rb +++ b/lib/hedgelog/normalizer.rb @@ -7,13 +7,13 @@ def normalize(data) end def normalize_struct(struct) - normalize_hash(Hash[struct.each_pair.to_a]) + normalize_hash(struct.each_pair.to_a.to_h) end def normalize_hash(hash) - Hash[hash.map do |key, val| - [key, normalize_thing(val)] - end] + hash.transform_values do |val| + normalize_thing(val) + end end def normalize_array(array) diff --git a/lib/hedgelog/version.rb b/lib/hedgelog/version.rb index cb74392..0a1592e 100755 --- a/lib/hedgelog/version.rb +++ b/lib/hedgelog/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Hedgelog - VERSION = '0.2.0' + VERSION = '0.2.1.alpha.2' end diff --git a/script/.bash_helpers b/script/.bash_helpers new file mode 100755 index 0000000..ba9c831 --- /dev/null +++ b/script/.bash_helpers @@ -0,0 +1,47 @@ +#!/bin/bash +base_dir=$(dirname $BASH_SOURCE) +. ${base_dir}/.env.colors + +die() +{ + echo + set_red + echo >&2 "$@" + reset_colors + exit 2 +} + +finish() +{ + echo + set_white + echo "$@" + reset_colors + exit 0 +} + +confirm() +{ + prompt="${1:-Are you sure? [y/N]}" + + set_yellow + echo -n "$prompt " + reset_colors + + if [ "${NO_INPUT:-}" == 'true' ] + then + # Continue if 'NO_INPUT' has been set + true + else + # call with a prompt string or use a default + read -r response + case "$response" in + [yY][eE][sS]|[yY]) + true + ;; + *) + false + ;; + esac + fi +} diff --git a/script/.env.colors b/script/.env.colors new file mode 100755 index 0000000..e4fcee9 --- /dev/null +++ b/script/.env.colors @@ -0,0 +1,94 @@ +#!/bin/bash + +echo_red() +{ + set_red + echo "$@" + reset_colors +} + +set_red() +{ + echo -ne "\033[31;1m" +} + +set_background_red() +{ + echo -ne "\033[41;1m" +} + +set_light_red() +{ + echo -ne "\033[91;1m" +} + +echo_green() +{ + set_green + echo "$@" + reset_colors +} + +set_green() +{ + echo -ne "\033[32;1m" +} + +set_background_green() +{ + echo -ne "\033[42;1m" +} + +set_light_green() +{ + echo -ne "\033[92;1m" +} + +echo_yellow() +{ + set_yellow + echo "$@" + reset_colors +} + +set_yellow() +{ + echo -ne "\033[33;1m" +} + +set_background_yellow() +{ + echo -ne "\033[43;1m" +} + +set_light_yellow() +{ + echo -ne "\033[93;1m" +} + +set_white() +{ + echo -ne "\033[37;1m" +} + +set_background_white() +{ + echo -ne "\033[47;1m" +} + +echo_light_white() +{ + set_light_white + echo "$@" + reset_colors +} + +set_light_white() +{ + echo -ne "\033[97;1m" +} + +reset_colors() +{ + echo -ne "\033[0m" +} diff --git a/script/.exit_handler b/script/.exit_handler new file mode 100755 index 0000000..a55b5c0 --- /dev/null +++ b/script/.exit_handler @@ -0,0 +1,50 @@ +#!/bin/bash +base_dir=$(dirname $BASH_SOURCE) +. ${base_dir}/.env.colors + +exit_handler() +{ + RETVAL=$? + + echo + if [ $RETVAL -eq 0 ] + then + echo_green " Command [ ${BASH_SOURCE[1]} ] completed successfully" + else + set +o xtrace + set_background_red + echo " Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]} - '${BASH_COMMAND}' exited with status $RETVAL" + + # Print out the stack trace + if [ ${#FUNCNAME[@]} -gt 2 ] + then + echo + echo " Stacktrace:" + for ((i=1;i<${#FUNCNAME[@]}-1;i++)) + do + echo " $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]} ${FUNCNAME[$i]}(...)" + done + fi + reset_colors + fi + + echo + exit $RETVAL +} + +int_handler() +{ + echo + echo_yellow " Ctrl-C received, exiting" + echo + exit 130 +} + +SHOULD_ADD_EXIT_HANDLER=${SHOULD_ADD_EXIT_HANDLER:-} +if [ "$SHOULD_ADD_EXIT_HANDLER" = '' ] +then + trap exit_handler EXIT + trap int_handler INT +fi +export SHOULD_ADD_EXIT_HANDLER=1 +set -o errtrace diff --git a/script/publish.sh b/script/publish.sh new file mode 100644 index 0000000..e69de29 diff --git a/spec/hedgelog/context_spec.rb b/spec/hedgelog/context_spec.rb index e05c34c..4ed6802 100644 --- a/spec/hedgelog/context_spec.rb +++ b/spec/hedgelog/context_spec.rb @@ -86,7 +86,6 @@ it 'updates the context with the merged data' do expect(instance[:foo]).to eq 'bar' instance.merge!(baz: 'qux') - expect(instance.to_h).to include(foo: 'bar', baz: 'qux') end end @@ -95,7 +94,6 @@ it 'updates the context with the merged data' do expect(instance[:foo]).to eq 'bar' instance.merge!(foo: 'qux') - expect(instance.to_h).to include(foo: 'bar') end end diff --git a/spec/hedgelog_spec.rb b/spec/hedgelog_spec.rb index d00e6e4..330bf09 100755 --- a/spec/hedgelog_spec.rb +++ b/spec/hedgelog_spec.rb @@ -20,7 +20,7 @@ end %w[debug info warn error fatal unknown].each do |level| - describe "\##{level}" do + describe "##{level}" do let(:log_level) { level.to_sym } before :each do Timecop.freeze(2015, 1, 1) @@ -199,7 +199,7 @@ end context 'and the logger is passed a block' do - let(:log_exec) { -> { logger.debug { raise Exception, 'This is not be evaluated' } } } + let(:log_exec) { -> { logger.debug { raise StandardError, 'This is not be evaluated' } } } it 'does not log the message' do expect(log_results).to be_empty diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index de48741..99654fc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -5,7 +5,7 @@ SimpleCov.minimum_coverage 99 -Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support', '**', '*.rb'))].each { |f| require f } +Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support', '**', '*.rb'))].sort.each { |f| require f } RSpec.configure do |config| config.include Matchers::Benchmark