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
- $stderr.write("Failed to submit event #{scope}/#{event} to #{name} endpoint: #{e.message}.\n")
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
@@ -1,3 +1,3 @@
1
1
  class StructuredEventLogger
2
- VERSION = "0.0.6"
2
+ VERSION = "0.1.0"
3
3
  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.6
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