alephant-logger-json 0.3.1 → 0.4.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
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