alephant-logger-json 0.3.1 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb999ad1fdc190e0cf59150933ec5f1e8e4403da
4
- data.tar.gz: b48484a0c9c855c2e5f95d79caf8b0173085051b
3
+ metadata.gz: 312008a258504317188c1b14bd2671bbe8c1cb57
4
+ data.tar.gz: 28bc444b2bb9b8001a56416c0c80860ceec0525c
5
5
  SHA512:
6
- metadata.gz: 8ddda013e92f5508ec2fdd7ce30caee46ebd01a468a5f14eccecf43fcf69b4398413e26570c5f09a5469f02b4394f7063def31e9f6b32dfe8091ed26b3f12997
7
- data.tar.gz: 808cd3d07ceca926a115624d4eab3653b76cda13510c7c632b795b2bd917bd469d2f53677a2a102a20f7e90a89b5a5dd7bce02aa54d648b9966070a50187e253
6
+ metadata.gz: 224caa6384c612f490e1a64a4c697224ae65f8b3faf8309c976172d22873d25be6f76c3362d19cb637cbb0817e5549c09fe8d232513f9e6631ab7366dbcf98b9
7
+ data.tar.gz: 7fc9d04d683e3e6dde99604e1b25eb559240b36503f59f3220323fc6940bfaf38edcbe28c23a14298f426cdc31e8c5309510d2733efed50f38509be9f5a17393
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require "bundler/gem_tasks"
2
- require "rake/rspec"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/rspec'
3
3
 
4
- task :default => :spec
4
+ task default: :spec
@@ -1,27 +1,27 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "alephant/logger/json/version"
4
+ require 'alephant/logger/json/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "alephant-logger-json"
7
+ spec.name = 'alephant-logger-json'
8
8
  spec.version = Alephant::Logger::JSON::VERSION
9
- spec.authors = ["Dan Arnould"]
10
- spec.email = ["dan@arnould.co.uk"]
11
- spec.summary = "alephant-logger driver enabling structured logging in JSON"
12
- spec.description = "alephant-logger driver enabling structured logging in JSON"
13
- spec.homepage = ""
14
- spec.license = "MIT"
9
+ spec.authors = ['Dan Arnould']
10
+ spec.email = ['dan@arnould.co.uk']
11
+ spec.summary = 'alephant-logger driver enabling structured logging in JSON'
12
+ spec.description = 'alephant-logger driver enabling structured logging in JSON'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.7"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec"
24
- spec.add_development_dependency "rspec-nc"
25
- spec.add_development_dependency "rake-rspec"
26
- spec.add_development_dependency "pry"
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'rspec-nc'
25
+ spec.add_development_dependency 'rake-rspec'
26
+ spec.add_development_dependency 'pry'
27
27
  end
@@ -7,7 +7,7 @@ module DynamicBinding
7
7
  def method_missing(m, *args)
8
8
  @bindings.reverse_each do |bind|
9
9
  begin
10
- method = eval("method(%s)" % m.inspect, bind)
10
+ method = eval('method(%s)' % m.inspect, bind)
11
11
  rescue NameError
12
12
  else
13
13
  return method.call(*args)
@@ -18,7 +18,7 @@ module DynamicBinding
18
18
  rescue NameError
19
19
  end
20
20
  end
21
- raise NoMethodError, "No such variable or method: %s" % m
21
+ raise NoMethodError, 'No such variable or method: %s' % m
22
22
  end
23
23
 
24
24
  def run_proc(p, *args)
@@ -1,7 +1,7 @@
1
1
  module Alephant
2
2
  module Logger
3
3
  class JSON
4
- VERSION = "0.3.1"
4
+ VERSION = '0.4.0'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,39 +1,46 @@
1
- require_relative "./dynamic_binding.rb"
2
- require "json"
1
+ require_relative './dynamic_binding.rb'
2
+ require 'json'
3
3
 
4
4
  module Alephant
5
5
  module Logger
6
6
  class JSON
7
7
  def initialize(log_path, options = {})
8
- @log_file = File.open(log_path, "a+")
9
- @log_file.sync = true
10
- @nesting = options.fetch(:nesting, false)
8
+ @log_file = File.open(log_path, 'a+')
9
+ @log_file.sync = true
10
+ @nesting = options.fetch(:nesting, false)
11
+ self.class.session = -> { 'n/a' } unless self.class.session?
11
12
  end
12
13
 
13
14
  [:debug, :info, :warn, :error].each do |level|
14
- define_method(level) do |b=nil, hash|
15
+ define_method(level) do |b = nil, hash|
15
16
  return if hash.is_a? String
16
- @@session = -> { "n/a" } unless defined? @@session
17
+
17
18
  h = {
18
- :timestamp => Time.now.to_s,
19
- :uuid => b.nil? ? "n/a" : @@session.call_with_binding(b),
20
- :level => level.to_s
21
- }.merge hash
22
- hash = flatten_values_to_s h unless @nesting
23
- @log_file.write(::JSON.generate(hash) + "\n")
19
+ timestamp: Time.now.to_s,
20
+ uuid: b.nil? ? 'n/a' : self.class.session.call_with_binding(b),
21
+ level: level.to_s
22
+ }.merge(hash)
23
+
24
+ hash = flatten_values_to_s(h) unless @nesting
25
+
26
+ write(hash)
24
27
  end
25
28
  end
26
29
 
27
- def self.session(fn)
28
- @@session = fn
29
- end
30
+ class << self
31
+ attr_accessor :session
30
32
 
31
- def self.session?
32
- defined?(@@session)
33
+ def session?
34
+ defined?(@session)
35
+ end
33
36
  end
34
37
 
35
38
  private
36
39
 
40
+ def write(hash)
41
+ @log_file.write(::JSON.generate(hash) + "\n")
42
+ end
43
+
37
44
  def flatten_values_to_s(hash)
38
45
  Hash[hash.map { |k, v| [k, v.to_s] }]
39
46
  end
@@ -0,0 +1,22 @@
1
+ require_relative 'json'
2
+ require 'json'
3
+
4
+ module Alephant
5
+ module Logger
6
+ class JSONtoIO < Alephant::Logger::JSON
7
+ attr_reader :output
8
+
9
+ def initialize(output, options = {})
10
+ @output = output
11
+ @nesting = options.fetch(:nesting, false)
12
+ self.class.session = -> { 'n/a' } unless self.class.session?
13
+ end
14
+
15
+ private
16
+
17
+ def write(hash)
18
+ output.puts(::JSON.generate(hash))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,14 +1,12 @@
1
- require "date"
2
- require "spec_helper"
3
- require "alephant/logger/json"
1
+ require 'date'
2
+ require 'spec_helper'
3
+ require 'alephant/logger/json'
4
4
 
5
5
  describe Alephant::Logger::JSON do
6
- subject do
7
- described_class.new log_path
8
- end
6
+ subject { described_class.new(log_path) }
9
7
 
10
- let(:fn) { -> { "foo" } }
11
- let(:log_path) { "/log/path.log" }
8
+ let(:fn) { -> { 'foo' } }
9
+ let(:log_path) { '/log/path.log' }
12
10
  let(:log_file) { instance_double File }
13
11
 
14
12
  before do
@@ -16,32 +14,32 @@ describe Alephant::Logger::JSON do
16
14
  allow(log_file).to receive :sync=
17
15
  end
18
16
 
19
- shared_examples "JSON logging" do
17
+ shared_examples 'JSON logging' do
20
18
  let(:log_hash) do
21
- { "foo" => "bar", "baz" => "quux" }
19
+ { 'foo' => 'bar', 'baz' => 'quux' }
22
20
  end
23
21
 
24
- it "writes JSON dump of hash to log with corresponding level key" do
25
- allow(Time).to receive(:now).and_return("foobar")
22
+ it 'writes JSON dump of hash to log with corresponding level key' do
23
+ allow(Time).to receive(:now).and_return('foobar')
26
24
 
27
25
  expect(log_file).to receive(:write) do |json_dump|
28
- h = { "timestamp" => "foobar", "uuid" => "n/a", "level" => level }
29
- expect(JSON.parse json_dump).to eq h.merge log_hash
26
+ h = { 'timestamp' => 'foobar', 'uuid' => 'n/a', 'level' => level }
27
+ expect(JSON.parse(json_dump)).to eq h.merge log_hash
30
28
  end
31
29
 
32
30
  subject.send(level, log_hash)
33
31
  end
34
32
 
35
- it "automatically includes a timestamp" do
33
+ it 'automatically includes a timestamp' do
36
34
  expect(log_file).to receive(:write) do |json_dump|
37
- t = JSON.parse(json_dump)["timestamp"]
38
- expect{DateTime.parse(t)}.to_not raise_error
35
+ t = JSON.parse(json_dump)['timestamp']
36
+ expect { DateTime.parse(t) }.to_not raise_error
39
37
  end
40
38
 
41
39
  subject.send(level, log_hash)
42
40
  end
43
41
 
44
- it "outputs the timestamp first" do
42
+ it 'outputs the timestamp first' do
45
43
  expect(log_file).to receive(:write) do |json_dump|
46
44
  h = JSON.parse(json_dump)
47
45
  expect(h.first[0].to_sym).to be :timestamp
@@ -50,69 +48,69 @@ describe Alephant::Logger::JSON do
50
48
  subject.send(level, log_hash)
51
49
  end
52
50
 
53
- it "displays a default session value if a custom function is not provided" do
51
+ it 'displays a default session value if a custom function is not provided' do
54
52
  expect(log_file).to receive(:write) do |json_dump|
55
53
  h = JSON.parse(json_dump)
56
- expect(h["uuid"]).to eq "n/a"
54
+ expect(h['uuid']).to eq 'n/a'
57
55
  end
58
56
 
59
57
  subject.send(level, log_hash)
60
58
  end
61
59
 
62
- it "displays a custom session value when provided a user defined function" do
60
+ it 'displays a custom session value when provided a user defined function' do
63
61
  expect(log_file).to receive(:write) do |json_dump|
64
62
  h = JSON.parse(json_dump)
65
- expect(h["uuid"]).to eq "foo"
63
+ expect(h['uuid']).to eq 'foo'
66
64
  end
67
65
 
68
- ::Alephant::Logger::JSON.session fn
66
+ described_class.session = fn
69
67
  subject.send(level, binding, log_hash)
70
- ::Alephant::Logger::JSON.session -> { "n/a" }
68
+ described_class.session = -> { 'n/a' }
71
69
  end
72
70
 
73
- it "provides a static method for checking if a session has been set" do
74
- ::Alephant::Logger::JSON.session fn
75
- expect(::Alephant::Logger::JSON.session?).to eq "class variable"
71
+ it 'provides a static method for checking if a session has been set' do
72
+ described_class.session = fn
73
+ expect(described_class.session?).to eq 'instance-variable'
76
74
 
77
- ::Alephant::Logger::JSON.remove_class_variable :@@session
78
- expect(::Alephant::Logger::JSON.session?).to eq nil
75
+ described_class.send(:remove_instance_variable, :@session)
76
+ expect(described_class.session?).to eq nil
79
77
  end
80
78
  end
81
79
 
82
- shared_context "nested log hash" do
80
+ shared_context 'nested log hash' do
83
81
  let(:log_hash) do
84
- { "nest" => nest }
82
+ { 'nest' => nest }
85
83
  end
86
84
 
87
- let(:nest) { { "bird" => "eggs" } }
85
+ let(:nest) { { 'bird' => 'eggs' } }
88
86
  end
89
87
 
90
- shared_examples "nests flattened to strings" do
91
- include_context "nested log hash"
88
+ shared_examples 'nests flattened to strings' do
89
+ include_context 'nested log hash'
92
90
 
93
91
  specify do
94
92
  expect(log_file).to receive(:write) do |json_dump|
95
- expect(JSON.parse(json_dump)["nest"]).to eq nest.to_s
93
+ expect(JSON.parse(json_dump)['nest']).to eq nest.to_s
96
94
  end
97
95
 
98
96
  subject.send(level, log_hash)
99
97
  end
100
98
  end
101
99
 
102
- shared_examples "nesting allowed" do
103
- include_context "nested log hash"
100
+ shared_examples 'nesting allowed' do
101
+ include_context 'nested log hash'
104
102
 
105
103
  specify do
106
104
  expect(log_file).to receive(:write) do |json_dump|
107
- expect(JSON.parse json_dump).to eq log_hash
105
+ expect(JSON.parse(json_dump)).to eq log_hash
108
106
  end
109
107
 
110
108
  subject.send(level, log_hash)
111
109
  end
112
110
  end
113
111
 
114
- shared_examples "gracefully fail with string arg" do
115
- let(:log_message) { "Unable to connect to server" }
112
+ shared_examples 'gracefully fail with string arg' do
113
+ let(:log_message) { 'Unable to connect to server' }
116
114
 
117
115
  specify { expect(log_file).not_to receive(:write) }
118
116
  specify do
@@ -124,18 +122,18 @@ describe Alephant::Logger::JSON do
124
122
  describe "##{level}" do
125
123
  let(:level) { level }
126
124
 
127
- it_behaves_like "JSON logging"
125
+ it_behaves_like 'JSON logging'
128
126
 
129
- it_behaves_like "nests flattened to strings"
127
+ it_behaves_like 'nests flattened to strings'
130
128
 
131
- it_behaves_like "gracefully fail with string arg"
129
+ it_behaves_like 'gracefully fail with string arg'
132
130
 
133
- context "with nesting allowed" do
131
+ context 'with nesting allowed' do
134
132
  subject do
135
- described_class.new(log_path, :nesting => true)
133
+ described_class.new(log_path, nesting: true)
136
134
  end
137
135
 
138
- it_behaves_like "nesting allowed"
136
+ it_behaves_like 'nesting allowed'
139
137
  end
140
138
  end
141
139
  end
@@ -0,0 +1,132 @@
1
+ require 'date'
2
+ require 'spec_helper'
3
+ require 'alephant/logger/json_to_io'
4
+
5
+ describe Alephant::Logger::JSONtoIO do
6
+ subject { described_class.new(logger_io) }
7
+
8
+ let(:fn) { -> { 'foo' } }
9
+ let(:logger_io) { spy }
10
+
11
+ shared_examples 'JSON logging' do
12
+ let(:log_hash) do
13
+ { 'foo' => 'bar', 'baz' => 'quux' }
14
+ end
15
+
16
+ it 'writes JSON dump of hash to log with corresponding level key' do
17
+ allow(Time).to receive(:now).and_return('foobar')
18
+
19
+ expect(logger_io).to receive(:puts) do |json_dump|
20
+ h = { 'timestamp' => 'foobar', 'uuid' => 'n/a', 'level' => level }
21
+ expect(JSON.parse(json_dump)).to eq h.merge log_hash
22
+ end
23
+
24
+ subject.public_send(level, log_hash)
25
+ end
26
+
27
+ it 'automatically includes a timestamp' do
28
+ expect(logger_io).to receive(:puts) do |json_dump|
29
+ t = JSON.parse(json_dump)['timestamp']
30
+ expect { DateTime.parse(t) }.to_not raise_error
31
+ end
32
+
33
+ subject.public_send(level, log_hash)
34
+ end
35
+
36
+ it 'outputs the timestamp first' do
37
+ expect(logger_io).to receive(:puts) do |json_dump|
38
+ h = JSON.parse(json_dump)
39
+ expect(h.first[0].to_sym).to be :timestamp
40
+ end
41
+
42
+ subject.public_send(level, log_hash)
43
+ end
44
+
45
+ it 'displays a default session value if a custom function is not provided' do
46
+ expect(logger_io).to receive(:puts) do |json_dump|
47
+ h = JSON.parse(json_dump)
48
+ expect(h['uuid']).to eq 'n/a'
49
+ end
50
+
51
+ subject.public_send(level, log_hash)
52
+ end
53
+
54
+ it 'displays a custom session value when provided a user defined function' do
55
+ expect(logger_io).to receive(:puts) do |json_dump|
56
+ h = JSON.parse(json_dump)
57
+ expect(h['uuid']).to eq 'foo'
58
+ end
59
+
60
+ described_class.session = fn
61
+ subject.send(level, binding, log_hash)
62
+ described_class.session = -> { 'n/a' }
63
+ end
64
+
65
+ it 'provides a static method for checking if a session has been set' do
66
+ described_class.session = fn
67
+ expect(described_class.session?).to eq 'instance-variable'
68
+
69
+ described_class.send(:remove_instance_variable, :@session)
70
+ expect(described_class.session?).to eq nil
71
+ end
72
+ end
73
+
74
+ shared_context 'nested log hash' do
75
+ let(:log_hash) do
76
+ { 'nest' => nest }
77
+ end
78
+
79
+ let(:nest) { { 'bird' => 'eggs' } }
80
+ end
81
+
82
+ shared_examples 'nests flattened to strings' do
83
+ include_context 'nested log hash'
84
+
85
+ specify do
86
+ expect(logger_io).to receive(:puts) do |json_dump|
87
+ expect(JSON.parse(json_dump)['nest']).to eq nest.to_s
88
+ end
89
+
90
+ subject.public_send(level, log_hash)
91
+ end
92
+ end
93
+
94
+ shared_examples 'nesting allowed' do
95
+ include_context 'nested log hash'
96
+
97
+ specify do
98
+ expect(logger_io).to receive(:puts) do |json_dump|
99
+ expect(JSON.parse(json_dump)).to eq log_hash
100
+ end
101
+
102
+ subject.public_send(level, log_hash)
103
+ end
104
+ end
105
+
106
+ shared_examples 'gracefully fail with string arg' do
107
+ let(:log_message) { 'Unable to connect to server' }
108
+
109
+ specify { expect(logger_io).not_to receive(:puts) }
110
+ specify do
111
+ expect { subject.debug log_message }.not_to raise_error
112
+ end
113
+ end
114
+
115
+ %w(debug info warn error).each do |level|
116
+ describe "##{level}" do
117
+ let(:level) { level }
118
+
119
+ it_behaves_like 'JSON logging'
120
+
121
+ it_behaves_like 'nests flattened to strings'
122
+
123
+ it_behaves_like 'gracefully fail with string arg'
124
+
125
+ context 'with nesting allowed' do
126
+ subject { described_class.new(logger_io, nesting: true) }
127
+
128
+ it_behaves_like 'nesting allowed'
129
+ end
130
+ end
131
+ end
132
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alephant-logger-json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Arnould
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-24 00:00:00.000000000 Z
11
+ date: 2016-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -111,7 +111,9 @@ files:
111
111
  - lib/alephant/logger/dynamic_binding.rb
112
112
  - lib/alephant/logger/json.rb
113
113
  - lib/alephant/logger/json/version.rb
114
+ - lib/alephant/logger/json_to_io.rb
114
115
  - spec/alephant/logger/json_spec.rb
116
+ - spec/alephant/logger/json_to_io_spec.rb
115
117
  - spec/spec_helper.rb
116
118
  homepage: ''
117
119
  licenses:
@@ -133,10 +135,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
135
  version: '0'
134
136
  requirements: []
135
137
  rubyforge_project:
136
- rubygems_version: 2.2.2
138
+ rubygems_version: 2.5.1
137
139
  signing_key:
138
140
  specification_version: 4
139
141
  summary: alephant-logger driver enabling structured logging in JSON
140
142
  test_files:
141
143
  - spec/alephant/logger/json_spec.rb
144
+ - spec/alephant/logger/json_to_io_spec.rb
142
145
  - spec/spec_helper.rb