structured-event-logger 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,32 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
3
|
class StructuredEventLogger
|
4
|
+
|
5
|
+
class Error < ::StandardError; end
|
6
|
+
|
7
|
+
class EndpointException < StructuredEventLogger::Error
|
8
|
+
attr_reader :name, :wrapped_exception
|
9
|
+
def initialize(name, wrapped_exception)
|
10
|
+
@name, @wrapped_exception = name, wrapped_exception
|
11
|
+
super("Endpoint #{name} failed - #{wrapped_exception.class.name}: #{wrapped_exception.message}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
attr_reader :endpoints, :default_context
|
16
|
+
attr_accessor :error_handler
|
5
17
|
|
6
18
|
def initialize(endpoints = {})
|
7
19
|
@endpoints = endpoints
|
8
20
|
|
9
21
|
@thread_contexts = {}
|
10
22
|
@default_context = {}
|
23
|
+
@error_handler = lambda { |exception| raise(exception) }
|
11
24
|
end
|
12
25
|
|
13
26
|
def event(scope, event, content = {})
|
14
27
|
log_event scope, event, flatten_hash(content)
|
28
|
+
rescue EndpointException => e
|
29
|
+
error_handler.call(e)
|
15
30
|
end
|
16
31
|
|
17
32
|
def context
|
@@ -42,7 +57,7 @@ class StructuredEventLogger
|
|
42
57
|
begin
|
43
58
|
endpoint.call(scope, event, hash, record)
|
44
59
|
rescue => e
|
45
|
-
|
60
|
+
raise EndpointException.new(name, e)
|
46
61
|
end
|
47
62
|
end
|
48
63
|
end
|
@@ -52,5 +67,6 @@ class StructuredEventLogger
|
|
52
67
|
end
|
53
68
|
end
|
54
69
|
|
70
|
+
require 'structured_event_logger/syslogger'
|
55
71
|
require 'structured_event_logger/json_writer'
|
56
72
|
require 'structured_event_logger/human_readable_logger'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'active_support/json'
|
3
|
+
require 'syslog'
|
4
|
+
|
5
|
+
class StructuredEventLogger::Syslogger
|
6
|
+
|
7
|
+
class MessageExceedsMaximumSize < StructuredEventLogger::Error; end
|
8
|
+
|
9
|
+
attr_accessor :log_level, :max_size
|
10
|
+
|
11
|
+
def initialize(log_level = Syslog::LOG_INFO, max_size = 64 * 1024 - 1)
|
12
|
+
@log_level, @max_size = log_level, max_size
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(scope, event, hash, record)
|
16
|
+
message = MultiJson.encode(record)
|
17
|
+
raise MessageExceedsMaximumSize, "Event too big to be submitted to syslog" if message.bytesize > max_size
|
18
|
+
Syslog.log(log_level, '%s', message)
|
19
|
+
end
|
20
|
+
end
|
@@ -15,6 +15,11 @@ class StructuredEventLoggerTest < Minitest::Test
|
|
15
15
|
|
16
16
|
Time.stubs(:now).returns(Time.parse('2012-01-01T05:00:00Z'))
|
17
17
|
SecureRandom.stubs(:uuid).returns('aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee')
|
18
|
+
Syslog.open('test_structured_event_logger') unless Syslog.opened?
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Syslog.close
|
18
23
|
end
|
19
24
|
|
20
25
|
def test_should_log_event_to_both_loggers
|
@@ -112,6 +117,47 @@ class StructuredEventLoggerTest < Minitest::Test
|
|
112
117
|
assert_last_event_does_not_contain :request_id
|
113
118
|
end
|
114
119
|
|
120
|
+
def test_should_submit_events_to_syslog
|
121
|
+
Syslog.expects(:log).with do |log_level, format_string, argument|
|
122
|
+
event_data = JSON.parse(argument)
|
123
|
+
assert_equal Syslog::LOG_INFO, log_level
|
124
|
+
assert_equal '%s', format_string
|
125
|
+
assert_equal 'test', event_data['event_scope']
|
126
|
+
assert_equal 'syslog', event_data['event_name']
|
127
|
+
assert_equal 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', event_data['event_uuid']
|
128
|
+
assert_equal '2012-01-01T05:00:00Z', event_data['event_timestamp']
|
129
|
+
assert_equal 'test', event_data['message']
|
130
|
+
end
|
131
|
+
|
132
|
+
@event_logger.endpoints[:syslog] = StructuredEventLogger::Syslogger.new
|
133
|
+
@event_logger.event(:test, :syslog, message: 'test')
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_should_fail_when_syslog_message_is_too_large
|
137
|
+
@event_logger.endpoints[:syslog] = StructuredEventLogger::Syslogger.new
|
138
|
+
assert_raises(StructuredEventLogger::EndpointException) do
|
139
|
+
@event_logger.event(:test, :syslog, message: 'a' * (64 * 1024 + 1))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_should_execute_a_custom_error_handler_on_failure
|
144
|
+
@event_logger.endpoints[:failer] = proc { raise "FAIL" }
|
145
|
+
@event_logger.error_handler = mock()
|
146
|
+
@event_logger.error_handler.expects(:call).with do |exception|
|
147
|
+
assert_kind_of StructuredEventLogger::EndpointException, exception
|
148
|
+
assert_equal 'FAIL', exception.wrapped_exception.message
|
149
|
+
assert_equal 'Endpoint failer failed - RuntimeError: FAIL', exception.message
|
150
|
+
end
|
151
|
+
@event_logger.event(:test, :fail)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_should_raise_exception_when_endpoint_fails
|
155
|
+
@event_logger.endpoints[:failer] = proc { raise "FAIL" }
|
156
|
+
assert_raises(StructuredEventLogger::EndpointException) do
|
157
|
+
@event_logger.event(:test, :fail)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
115
161
|
private
|
116
162
|
|
117
163
|
def assert_last_event_contains_value(value, key)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: structured-event-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -127,6 +127,7 @@ files:
|
|
127
127
|
- lib/structured_event_logger.rb
|
128
128
|
- lib/structured_event_logger/human_readable_logger.rb
|
129
129
|
- lib/structured_event_logger/json_writer.rb
|
130
|
+
- lib/structured_event_logger/syslogger.rb
|
130
131
|
- lib/structured_event_logger/version.rb
|
131
132
|
- structured-event-logger.gemspec
|
132
133
|
- test/structured_event_logger_test.rb
|