yarder 0.0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.md +87 -0
- data/Rakefile +38 -0
- data/lib/tasks/yarder_tasks.rake +4 -0
- data/lib/yarder.rb +15 -0
- data/lib/yarder/action_controller/log_subscriber.rb +74 -0
- data/lib/yarder/action_view/log_subscriber.rb +31 -0
- data/lib/yarder/active_record/log_subscriber.rb +75 -0
- data/lib/yarder/active_resource/log_subscriber.rb +34 -0
- data/lib/yarder/configuration.rb +8 -0
- data/lib/yarder/core_ext/object/blank.rb +105 -0
- data/lib/yarder/logger.rb +55 -0
- data/lib/yarder/rack/logger.rb +72 -0
- data/lib/yarder/railtie.rb +69 -0
- data/lib/yarder/tagged_logging.rb +102 -0
- data/lib/yarder/version.rb +3 -0
- data/test/action_controller/log_subscriber_test.rb +165 -0
- data/test/action_view/log_subscriber_test.rb +89 -0
- data/test/active_record/log_subscriber_test.rb +87 -0
- data/test/active_resource/log_subscriber_test.rb +42 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/javascripts/widgets.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/test/dummy/app/assets/stylesheets/widgets.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/log_subscriber_controller.rb +56 -0
- data/test/dummy/app/controllers/widgets_controller.rb +83 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/widgets_helper.rb +2 -0
- data/test/dummy/app/models/widget.rb +3 -0
- data/test/dummy/app/views/customers/_customer.html.erb +1 -0
- data/test/dummy/app/views/good_customers/_good_customer.html.erb +1 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/test/_customer.erb +1 -0
- data/test/dummy/app/views/test/hello_world.erb +1 -0
- data/test/dummy/app/views/widgets/_form.html.erb +17 -0
- data/test/dummy/app/views/widgets/edit.html.erb +6 -0
- data/test/dummy/app/views/widgets/index.html.erb +21 -0
- data/test/dummy/app/views/widgets/new.html.erb +5 -0
- data/test/dummy/app/views/widgets/show.html.erb +5 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +69 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +31 -0
- data/test/dummy/config/environments/production.rb +64 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +69 -0
- data/test/dummy/db/migrate/20120927084605_create_widgets.rb +8 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/log/development.log +19 -0
- data/test/dummy/log/test.log +10694 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/logger_test.rb +126 -0
- data/test/rack/logger_test.rb +68 -0
- data/test/support/fake_models.rb +12 -0
- data/test/support/integration_case.rb +5 -0
- data/test/support/multibyte_test_helpers.rb +19 -0
- data/test/tagged_logging_test.rb +155 -0
- data/test/test_helper.rb +31 -0
- data/test/yarder_test.rb +7 -0
- metadata +236 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/422.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
</div>
|
24
|
+
</body>
|
25
|
+
</html>
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
data/test/logger_test.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'test_helper'
|
5
|
+
|
6
|
+
class BufferedLoggerTest < ActiveSupport::TestCase
|
7
|
+
include MultibyteTestHelpers
|
8
|
+
|
9
|
+
Logger = Yarder::Logger
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@message = "A debug message"
|
13
|
+
@integer_message = 12345
|
14
|
+
@output = StringIO.new
|
15
|
+
@logger = Logger.new(@output)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_write_binary_data_to_existing_file
|
19
|
+
t = Tempfile.new ['development', 'log']
|
20
|
+
t.binmode
|
21
|
+
t.write 'hi mom!'
|
22
|
+
t.close
|
23
|
+
|
24
|
+
f = File.open(t.path, 'w')
|
25
|
+
f.binmode
|
26
|
+
|
27
|
+
logger = Logger.new f
|
28
|
+
logger.level = Logger::DEBUG
|
29
|
+
|
30
|
+
str = "\x80"
|
31
|
+
str.force_encoding("ASCII-8BIT")
|
32
|
+
|
33
|
+
logger.add Logger::DEBUG, str
|
34
|
+
ensure
|
35
|
+
logger.close
|
36
|
+
t.close true
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_write_binary_data_create_file
|
40
|
+
fname = File.join Dir.tmpdir, 'lol', 'rofl.log'
|
41
|
+
FileUtils.mkdir_p File.dirname(fname)
|
42
|
+
f = File.open(fname, 'w')
|
43
|
+
f.binmode
|
44
|
+
|
45
|
+
logger = Logger.new f
|
46
|
+
logger.level = Logger::DEBUG
|
47
|
+
|
48
|
+
str = "\x80"
|
49
|
+
str.force_encoding("ASCII-8BIT")
|
50
|
+
|
51
|
+
logger.add Logger::DEBUG, str
|
52
|
+
ensure
|
53
|
+
logger.close
|
54
|
+
File.unlink fname
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_log_debugging_message_when_debugging
|
58
|
+
@logger.level = Logger::DEBUG
|
59
|
+
@logger.add(Logger::DEBUG, @message)
|
60
|
+
assert @output.string.include?(@message)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_not_log_debug_messages_when_log_level_is_info
|
64
|
+
@logger.level = Logger::INFO
|
65
|
+
@logger.add(Logger::DEBUG, @message)
|
66
|
+
assert ! @output.string.include?(@message)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_add_message_passed_as_block_when_using_add
|
70
|
+
@logger.level = Logger::INFO
|
71
|
+
@logger.add(Logger::INFO) {@message}
|
72
|
+
assert @output.string.include?(@message)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_add_message_passed_as_block_when_using_shortcut
|
76
|
+
@logger.level = Logger::INFO
|
77
|
+
@logger.info {@message}
|
78
|
+
assert @output.string.include?(@message)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_convert_message_to_string
|
82
|
+
@logger.level = Logger::INFO
|
83
|
+
@logger.info @integer_message
|
84
|
+
assert @output.string.include?(@integer_message.to_s)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_convert_message_to_string_when_passed_in_block
|
88
|
+
@logger.level = Logger::INFO
|
89
|
+
@logger.info {@integer_message}
|
90
|
+
assert @output.string.include?(@integer_message.to_s)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_not_evaluate_block_if_message_wont_be_logged
|
94
|
+
@logger.level = Logger::INFO
|
95
|
+
evaluated = false
|
96
|
+
@logger.add(Logger::DEBUG) {evaluated = true}
|
97
|
+
assert evaluated == false
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_not_mutate_message
|
101
|
+
message_copy = @message.dup
|
102
|
+
@logger.info @message
|
103
|
+
assert_equal message_copy, @message
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_know_if_its_loglevel_is_below_a_given_level
|
107
|
+
Logger::Severity.constants.each do |level|
|
108
|
+
next if level.to_s == 'UNKNOWN'
|
109
|
+
@logger.level = Logger::Severity.const_get(level) - 1
|
110
|
+
assert @logger.send("#{level.downcase}?"), "didn't know if it was #{level.downcase}? or below"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# This test will fail on JRuby versions lower than 1.7 due to UTF-8 Encoding issues
|
115
|
+
# so only run on MRI and JRuby 1.7 and later
|
116
|
+
unless defined?(JRUBY_VERSION) && JRUBY_VERSION.to_f < 1.7
|
117
|
+
def test_buffer_multibyte
|
118
|
+
@logger.info(UNICODE_STRING)
|
119
|
+
@logger.info(BYTE_STRING)
|
120
|
+
assert @output.string.include?(UNICODE_STRING)
|
121
|
+
byte_string = @output.string.dup
|
122
|
+
byte_string.force_encoding("ASCII-8BIT")
|
123
|
+
assert byte_string.include?(BYTE_STRING)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# TODO These tests are fragile because they rely on the output being added
|
4
|
+
# to the last line of the log file. See if there is a better way to do this
|
5
|
+
class LoggerTest < ActiveSupport::IntegrationCase
|
6
|
+
class MyLogger < Yarder::Logger
|
7
|
+
def flush(*)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
setup do
|
13
|
+
@output = StringIO.new
|
14
|
+
Rails.logger = Yarder::TaggedLogging.new(MyLogger.new(@output))
|
15
|
+
visit('/widgets')
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'writes a hash to the log file when a request is received' do
|
19
|
+
assert_equal Hash, entry.class
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'fills in the client_ip' do
|
23
|
+
assert_equal "127.0.0.1", entry['@fields']['client_ip']
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'fills in the method' do
|
27
|
+
assert_equal "GET", entry['@fields']['method']
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'fills in the path' do
|
31
|
+
assert_equal "/widgets", entry['@fields']['path']
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'fills in the status' do
|
35
|
+
assert_equal "/widgets", entry['@fields']['path']
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'fills in the total_duration' do
|
39
|
+
assert entry['@fields']['total_duration'].to_f >= 0, "total_duration was not a positive number"
|
40
|
+
end
|
41
|
+
|
42
|
+
test 'fills in the rendering_duration' do
|
43
|
+
assert entry['@fields']['rendering_duration'].to_f >= 0, "rendering_duration was not a positive number"
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'fills in the sql_duration' do
|
47
|
+
assert entry['@fields']['rendering_duration'].to_f >= 0, "sql_duration was not a positive number"
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'fills in the method name tag' do
|
51
|
+
assert_equal 32, entry['@fields']['uuid'].size
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'fills in the string tag' do
|
55
|
+
assert_match "Hello", entry['@tags'].first
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'fills in the proc tag' do
|
59
|
+
assert_match "Proc", entry['@tags'].last
|
60
|
+
end
|
61
|
+
|
62
|
+
#TODO Add tests for view and SQL rendering summaries
|
63
|
+
|
64
|
+
def entry
|
65
|
+
JSON.parse(@output.string)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module MultibyteTestHelpers
|
4
|
+
UNICODE_STRING = 'こにちわ'
|
5
|
+
ASCII_STRING = 'ohayo'
|
6
|
+
BYTE_STRING = "\270\236\010\210\245".force_encoding("ASCII-8BIT")
|
7
|
+
|
8
|
+
def chars(str)
|
9
|
+
ActiveSupport::Multibyte::Chars.new(str)
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect_codepoints(str)
|
13
|
+
str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ')
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_equal_codepoints(expected, actual, message=nil)
|
17
|
+
assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'yarder/logger'
|
2
|
+
require 'yarder/tagged_logging'
|
3
|
+
|
4
|
+
class TaggedLoggingTest < ActiveSupport::TestCase
|
5
|
+
class MyLogger < Yarder::Logger
|
6
|
+
end
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@output = StringIO.new
|
10
|
+
@logger = Yarder::TaggedLogging.new(MyLogger.new(@output))
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'sets logger.formatter if missing and extends it with a tagging API' do
|
14
|
+
logger = ::Logger.new(StringIO.new)
|
15
|
+
# assert_nil logger.formatter #TODO This assertion is failing but I do not think it is end of the world
|
16
|
+
Yarder::TaggedLogging.new(logger)
|
17
|
+
assert_not_nil logger.formatter
|
18
|
+
assert logger.formatter.respond_to?(:tagged)
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'fills in the severity' do
|
22
|
+
@logger.info "Severity Test"
|
23
|
+
assert_equal "INFO", JSON.parse(@output.string)['@fields']['severity']
|
24
|
+
end
|
25
|
+
|
26
|
+
test "tagged once" do
|
27
|
+
@logger.tagged("BCX") { @logger.info "Funky time" }
|
28
|
+
assert_equal "BCX", JSON.parse(@output.string)['@tags'][0]
|
29
|
+
assert_equal "Funky time", JSON.parse(@output.string)['@message']
|
30
|
+
end
|
31
|
+
|
32
|
+
test "tagged twice" do
|
33
|
+
@logger.tagged("BCX") { @logger.tagged("Jason") { @logger.info "Funky time" } }
|
34
|
+
assert_equal "BCX", JSON.parse(@output.string)['@tags'][0]
|
35
|
+
assert_equal "Jason", JSON.parse(@output.string)['@tags'][1]
|
36
|
+
end
|
37
|
+
|
38
|
+
test "tagged thrice at once" do
|
39
|
+
@logger.tagged("BCX", "Jason", "New") { @logger.info "Funky time" }
|
40
|
+
assert_equal "BCX", JSON.parse(@output.string)['@tags'][0]
|
41
|
+
assert_equal "Jason", JSON.parse(@output.string)['@tags'][1]
|
42
|
+
assert_equal "New", JSON.parse(@output.string)['@tags'][2]
|
43
|
+
end
|
44
|
+
|
45
|
+
test "tagged are flattened" do
|
46
|
+
@logger.tagged("BCX", %w(Jason New)) { @logger.info "Funky time" }
|
47
|
+
assert_equal "BCX", JSON.parse(@output.string)['@tags'][0]
|
48
|
+
assert_equal "Jason", JSON.parse(@output.string)['@tags'][1]
|
49
|
+
assert_equal "New", JSON.parse(@output.string)['@tags'][2]
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
test "push and pop tags directly" do
|
54
|
+
assert_equal %w(A B C), @logger.push_tags('A', ['B', ' ', ['C']])
|
55
|
+
@logger.info 'a'
|
56
|
+
assert_equal %w(C), @logger.pop_tags
|
57
|
+
@logger.info 'b'
|
58
|
+
assert_equal %w(B), @logger.pop_tags(1)
|
59
|
+
@logger.info 'c'
|
60
|
+
assert_equal [], @logger.clear_tags!
|
61
|
+
@logger.info 'd'
|
62
|
+
# assert_equal "[A] [B] [C] a\n[A] [B] b\n[A] c\nd\n", JSON.parse(@output.string)['@tags']
|
63
|
+
|
64
|
+
first_log = JSON.parse(@output.string.split("\n")[0])
|
65
|
+
assert_equal "A", first_log['@tags'][0]
|
66
|
+
assert_equal "B", first_log['@tags'][1]
|
67
|
+
assert_equal "C", first_log['@tags'][2]
|
68
|
+
assert_equal "a", first_log['@message']
|
69
|
+
|
70
|
+
second_log = JSON.parse(@output.string.split("\n")[1])
|
71
|
+
assert_equal "A", second_log['@tags'][0]
|
72
|
+
assert_equal "B", second_log['@tags'][1]
|
73
|
+
assert_equal "b", second_log['@message']
|
74
|
+
|
75
|
+
third_log = JSON.parse(@output.string.split("\n")[2])
|
76
|
+
assert_equal "A", third_log['@tags'][0]
|
77
|
+
assert_equal "c", third_log['@message']
|
78
|
+
|
79
|
+
fourth_log = JSON.parse(@output.string.split("\n")[3])
|
80
|
+
assert fourth_log['@tags'].empty?
|
81
|
+
assert_equal "d", fourth_log['@message']
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
test "does not strip message content" do
|
87
|
+
@logger.info " Hello"
|
88
|
+
assert_equal " Hello", JSON.parse(@output.string)['@message']
|
89
|
+
end
|
90
|
+
|
91
|
+
test "provides access to the logger instance" do
|
92
|
+
@logger.tagged("BCX") { |logger| logger.info "Funky time" }
|
93
|
+
assert_equal "BCX", JSON.parse(@output.string)['@tags'][0]
|
94
|
+
assert_equal "Funky time", JSON.parse(@output.string)['@message']
|
95
|
+
end
|
96
|
+
|
97
|
+
test "tagged once with blank and nil" do
|
98
|
+
@logger.tagged(nil, "", "New") { @logger.info "Funky time" }
|
99
|
+
assert_equal "New", JSON.parse(@output.string)['@tags'].last
|
100
|
+
end
|
101
|
+
|
102
|
+
test "keeps each tag in their own thread" do
|
103
|
+
@logger.tagged("BCX") do
|
104
|
+
Thread.new do
|
105
|
+
@logger.tagged("OMG") { @logger.info "Cool story bro" }
|
106
|
+
end.join
|
107
|
+
@logger.info "Funky time"
|
108
|
+
end
|
109
|
+
|
110
|
+
# Sub-thread
|
111
|
+
main_thread = JSON.parse(@output.string.split("\n").first)
|
112
|
+
assert_equal "OMG", main_thread['@tags'][0]
|
113
|
+
assert_equal "Cool story bro", main_thread['@message']
|
114
|
+
|
115
|
+
# Main thread
|
116
|
+
main_thread = JSON.parse(@output.string.split("\n").last)
|
117
|
+
assert_equal "BCX", main_thread['@tags'][0]
|
118
|
+
assert_equal "Funky time", main_thread['@message']
|
119
|
+
end
|
120
|
+
|
121
|
+
test "cleans up the taggings on flush" do
|
122
|
+
@logger.tagged("BCX") do
|
123
|
+
Thread.new do
|
124
|
+
@logger.tagged("OMG") do
|
125
|
+
@logger.flush
|
126
|
+
@logger.info "Cool story bro"
|
127
|
+
end
|
128
|
+
end.join
|
129
|
+
end
|
130
|
+
|
131
|
+
first_log = JSON.parse(@output.string.split("\n").first)
|
132
|
+
assert first_log['@tags'].empty?
|
133
|
+
assert_equal "Cool story bro", first_log['@message']
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
test "mixed levels of tagging" do
|
138
|
+
@logger.tagged("BCX") do
|
139
|
+
@logger.tagged("Jason") { @logger.info "Funky time" }
|
140
|
+
@logger.info "Junky time!"
|
141
|
+
end
|
142
|
+
|
143
|
+
first_log = JSON.parse(@output.string.split("\n").first)
|
144
|
+
assert_equal "BCX", first_log['@tags'][0]
|
145
|
+
assert_equal "Jason", first_log['@tags'][1]
|
146
|
+
assert_equal "Funky time", first_log['@message']
|
147
|
+
|
148
|
+
second_log = JSON.parse(@output.string.split("\n").last)
|
149
|
+
assert_equal "BCX", second_log['@tags'][0]
|
150
|
+
assert_equal "Junky time!", second_log['@message']
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
|