semantic_logger 4.6.1 → 4.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -20
  3. data/Rakefile +7 -7
  4. data/lib/semantic_logger/appender/async.rb +10 -9
  5. data/lib/semantic_logger/appender/async_batch.rb +7 -3
  6. data/lib/semantic_logger/appender/bugsnag.rb +43 -30
  7. data/lib/semantic_logger/appender/elasticsearch.rb +32 -14
  8. data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
  9. data/lib/semantic_logger/appender/file.rb +249 -67
  10. data/lib/semantic_logger/appender/graylog.rb +12 -10
  11. data/lib/semantic_logger/appender/honeybadger.rb +3 -3
  12. data/lib/semantic_logger/appender/http.rb +20 -18
  13. data/lib/semantic_logger/appender/io.rb +68 -0
  14. data/lib/semantic_logger/appender/kafka.rb +9 -5
  15. data/lib/semantic_logger/appender/mongodb.rb +6 -6
  16. data/lib/semantic_logger/appender/new_relic.rb +2 -2
  17. data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
  18. data/lib/semantic_logger/appender/sentry.rb +7 -7
  19. data/lib/semantic_logger/appender/sentry_ruby.rb +138 -0
  20. data/lib/semantic_logger/appender/splunk.rb +6 -5
  21. data/lib/semantic_logger/appender/splunk_http.rb +6 -6
  22. data/lib/semantic_logger/appender/syslog.rb +23 -15
  23. data/lib/semantic_logger/appender/tcp.rb +5 -5
  24. data/lib/semantic_logger/appender/udp.rb +2 -2
  25. data/lib/semantic_logger/appender/wrapper.rb +3 -2
  26. data/lib/semantic_logger/appender.rb +42 -36
  27. data/lib/semantic_logger/appenders.rb +34 -30
  28. data/lib/semantic_logger/base.rb +57 -27
  29. data/lib/semantic_logger/formatters/base.rb +9 -3
  30. data/lib/semantic_logger/formatters/color.rb +12 -8
  31. data/lib/semantic_logger/formatters/default.rb +18 -5
  32. data/lib/semantic_logger/formatters/fluentd.rb +3 -3
  33. data/lib/semantic_logger/formatters/json.rb +1 -1
  34. data/lib/semantic_logger/formatters/logfmt.rb +72 -0
  35. data/lib/semantic_logger/formatters/raw.rb +31 -7
  36. data/lib/semantic_logger/formatters/signalfx.rb +10 -9
  37. data/lib/semantic_logger/formatters/syslog.rb +8 -6
  38. data/lib/semantic_logger/formatters/syslog_cee.rb +8 -6
  39. data/lib/semantic_logger/formatters.rb +12 -13
  40. data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
  41. data/lib/semantic_logger/levels.rb +9 -7
  42. data/lib/semantic_logger/log.rb +51 -61
  43. data/lib/semantic_logger/loggable.rb +8 -1
  44. data/lib/semantic_logger/logger.rb +19 -11
  45. data/lib/semantic_logger/metric/new_relic.rb +3 -3
  46. data/lib/semantic_logger/metric/signalfx.rb +3 -3
  47. data/lib/semantic_logger/metric/statsd.rb +7 -7
  48. data/lib/semantic_logger/processor.rb +9 -7
  49. data/lib/semantic_logger/reporters/minitest.rb +4 -4
  50. data/lib/semantic_logger/semantic_logger.rb +40 -19
  51. data/lib/semantic_logger/subscriber.rb +16 -5
  52. data/lib/semantic_logger/sync.rb +12 -0
  53. data/lib/semantic_logger/sync_processor.rb +43 -0
  54. data/lib/semantic_logger/test/capture_log_events.rb +34 -0
  55. data/lib/semantic_logger/utils.rb +32 -13
  56. data/lib/semantic_logger/version.rb +1 -1
  57. data/lib/semantic_logger.rb +27 -22
  58. metadata +15 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22f95d79aaeb38befe2e1c242063464be93f05d16eed7cf17540256c1064f7b2
4
- data.tar.gz: 2ae7b4e00a4415c88d66afd552c4fa03e68dcf2d354994bfe98621d0e08bcdd0
3
+ metadata.gz: 2ff7d4bcb345581f6ba19f834bb1bf2f921e97904f4b6236142b87af75a4526d
4
+ data.tar.gz: b1069d5360296c61c9796f630b1ec065eb1a0a7dc549778c66c5e26c90d0eadb
5
5
  SHA512:
6
- metadata.gz: bc5bd0ce964de270119c5ef3bcab46c8178eb7120c5ad76afd99c0f5c1acbe4d7011eaf88c4d983e943d1e25f09baffd803121cba5a580be168ac874f09e539e
7
- data.tar.gz: 0e64868d3f9363007114fce5c10ced420282edd098816df92e60da755c380434fe42075b5be3ebcb8ca03ff2b8746681a30317e33b88563bd2e3af5579ad9b4f
6
+ metadata.gz: c5cfbac7dd8795b11cf79ed3fa9a4a086128d5ee030f0e9db40b75f30f58997c1674a4284b4b287939216bc8de83372e2b7fe00d73e7856c3cc6830310740f0d
7
+ data.tar.gz: 2150a809562247d771103a5d387ae5852ff5b0649a4f4288a7dd07a94420bafcfb6b36f3e21077fcc053c2d8bcaffe80a110ab65b52178fb612b7368fd79d87d
data/README.md CHANGED
@@ -1,25 +1,13 @@
1
1
  # Semantic Logger
2
- [![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://travis-ci.org/rocketjob/semantic_logger.svg?branch=master)](https://travis-ci.org/rocketjob/semantic_logger) [![Downloads](https://img.shields.io/gem/dt/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg) [![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-Support-brightgreen.svg)](https://gitter.im/rocketjob/support)
2
+ [![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://github.com/reidmorrison/semantic_logger/workflows/build/badge.svg)](https://github.com/reidmorrison/semantic_logger/actions?query=workflow%3Abuild) [![Downloads](https://img.shields.io/gem/dt/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg)
3
3
 
4
4
  Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
5
5
 
6
- * https://rocketjob.github.io/semantic_logger/
6
+ * https://logger.rocketjob.io/
7
7
 
8
8
  ## Documentation
9
9
 
10
- [Semantic Logger Guide](http://rocketjob.github.io/semantic_logger)
11
-
12
- [Reference Documentation](http://www.rubydoc.info/gems/semantic_logger/)
13
-
14
- ## Upgrading to Semantic Logger v4.4
15
-
16
- With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
17
- workaround for Ruby 2.5 crashes is no longer needed.
18
- I.e. Please remove the following line if being called anywhere:
19
-
20
- ~~~ruby
21
- SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
22
- ~~~
10
+ [Semantic Logger Guide](https://logger.rocketjob.io/)
23
11
 
24
12
  ## Logging Destinations
25
13
 
@@ -34,7 +22,7 @@ Logging to the following destinations are all supported "out-of-the-box":
34
22
  * Splunk
35
23
  * MongoDB
36
24
  * Honeybadger
37
- * Sentry
25
+ * Sentry (both with legacy `sentry-raven` and modern `sentry-ruby` gem)
38
26
  * HTTP
39
27
  * TCP
40
28
  * UDP
@@ -50,7 +38,7 @@ handles saving log information to multiple destinations / appenders.
50
38
 
51
39
  ## Rails
52
40
 
53
- When running Rails, use [rails_semantic_logger](http://github.com/rocketjob/rails_semantic_logger)
41
+ When running Rails, use [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
54
42
  instead of Semantic Logger directly since it will automatically replace the Rails default logger with Semantic Logger.
55
43
 
56
44
  ## Rocket Job
@@ -72,8 +60,50 @@ and are therefore not automatically included by this gem:
72
60
  - Splunk Appender: gem 'splunk-sdk-ruby'
73
61
  - Elasticsearch Appender: gem 'elasticsearch'
74
62
  - Kafka Appender: gem 'ruby-kafka'
63
+ - Legacy Sentry Appender: gem 'sentry-raven' (deprecated)
64
+ - Sentry Appender: gem 'sentry-ruby'
65
+
66
+ ## Upgrading to Semantic Logger v4.9
67
+
68
+ These changes should not be noticeable by the majority of users of Semantic Logger, since
69
+ they are to the internal API. It is possible that advanced users may be using these internal
70
+ API's directly.
71
+
72
+ This does not affect any calls to the public api `SemanticLogger.add_appender`.
73
+
74
+ File and IO are now separate appenders. When creating the File appender explicitly, its arguments
75
+ have changed. For example, when requesting an IO stream, it needs to be changed from:
76
+
77
+ ~~~ruby
78
+ SemanticLogger::Appender::File.new(io: $stderr)
79
+ ~~~
80
+ to:
81
+ ~~~ruby
82
+ SemanticLogger::Appender::IO.new($stderr)
83
+ ~~~
84
+
85
+ Additionally, this needs to be changed from:
86
+ ~~~ruby
87
+ SemanticLogger::Appender::File.new(file_name: "file.log")
88
+ ~~~
89
+ to:
90
+ ~~~ruby
91
+ SemanticLogger::Appender::File.new("file.log")
92
+ ~~~
93
+
94
+ Rails Semantic Logger, if used, needs to be upgraded to v4.9 when upgrading to Semantic Logger v4.9.
95
+
96
+ ## Upgrading to Semantic Logger v4.4
97
+
98
+ With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
99
+ workaround for Ruby 2.5 crashes is no longer needed.
100
+ I.e. Please remove the following line if being called anywhere:
101
+
102
+ ~~~ruby
103
+ SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
104
+ ~~~
75
105
 
76
- ## V4 Upgrade notes
106
+ ## Upgrading to Semantic Logger v4.0
77
107
 
78
108
  The following changes need to be made when upgrading to V4:
79
109
  - Ruby V2.3 / JRuby V9.1 is now the minimum runtime version.
@@ -129,13 +159,13 @@ SemanticLogger.default_level = :trace
129
159
  SemanticLogger.add_appender(file_name: 'development.log', formatter: :color)
130
160
  ~~~
131
161
 
132
- If running rails, see: [Semantic Logger Rails](http://rocketjob.github.io/semantic_logger/rails.html)
162
+ If running rails, see: [Semantic Logger Rails](https://logger.rocketjob.io/rails.html)
133
163
 
134
164
  ## Author
135
165
 
136
166
  [Reid Morrison](https://github.com/reidmorrison)
137
167
 
138
- [Contributors](https://github.com/rocketjob/semantic_logger/graphs/contributors)
168
+ [Contributors](https://github.com/reidmorrison/semantic_logger/graphs/contributors)
139
169
 
140
170
  ## Versioning
141
171
 
data/Rakefile CHANGED
@@ -1,22 +1,22 @@
1
- require 'rake/clean'
2
- require 'rake/testtask'
1
+ require "rake/clean"
2
+ require "rake/testtask"
3
3
 
4
- $LOAD_PATH.unshift File.expand_path('lib', __dir__)
5
- require 'semantic_logger/version'
4
+ $LOAD_PATH.unshift File.expand_path("lib", __dir__)
5
+ require "semantic_logger/version"
6
6
 
7
7
  task :gem do
8
- system 'gem build semantic_logger.gemspec'
8
+ system "gem build semantic_logger.gemspec"
9
9
  end
10
10
 
11
11
  task publish: :gem do
12
12
  system "git tag -a v#{SemanticLogger::VERSION} -m 'Tagging #{SemanticLogger::VERSION}'"
13
- system 'git push --tags'
13
+ system "git push --tags"
14
14
  system "gem push semantic_logger-#{SemanticLogger::VERSION}.gem"
15
15
  system "rm semantic_logger-#{SemanticLogger::VERSION}.gem"
16
16
  end
17
17
 
18
18
  Rake::TestTask.new(:test) do |t|
19
- t.pattern = 'test/**/*_test.rb'
19
+ t.pattern = "test/**/*_test.rb"
20
20
  t.verbose = true
21
21
  t.warning = false
22
22
  end
@@ -1,4 +1,4 @@
1
- require 'forwardable'
1
+ require "forwardable"
2
2
 
3
3
  module SemanticLogger
4
4
  module Appender
@@ -53,7 +53,7 @@ module SemanticLogger
53
53
  # Re-open appender after a fork
54
54
  def reopen
55
55
  # Workaround CRuby crash on fork by recreating queue on reopen
56
- # https://github.com/rocketjob/semantic_logger/issues/103
56
+ # https://github.com/reidmorrison/semantic_logger/issues/103
57
57
  @queue&.close
58
58
  create_queue
59
59
 
@@ -73,6 +73,7 @@ module SemanticLogger
73
73
  # Starts the worker thread if not running.
74
74
  def thread
75
75
  return @thread if @thread&.alive?
76
+
76
77
  @thread = Thread.new { process }
77
78
  end
78
79
 
@@ -115,21 +116,21 @@ module SemanticLogger
115
116
  # This thread is designed to never go down unless the main thread terminates
116
117
  # or the appender is closed.
117
118
  Thread.current.name = logger.name
118
- logger.trace 'Async: Appender thread active'
119
+ logger.trace "Async: Appender thread active"
119
120
  begin
120
121
  process_messages
121
- rescue StandardError => exception
122
+ rescue StandardError => e
122
123
  # This block may be called after the file handles have been released by Ruby
123
124
  begin
124
- logger.error('Async: Restarting due to exception', exception)
125
+ logger.error("Async: Restarting due to exception", e)
125
126
  rescue StandardError
126
127
  nil
127
128
  end
128
129
  retry
129
- rescue Exception => exception
130
+ rescue Exception => e
130
131
  # This block may be called after the file handles have been released by Ruby
131
132
  begin
132
- logger.error('Async: Stopping due to fatal exception', exception)
133
+ logger.error("Async: Stopping due to fatal exception", e)
133
134
  rescue StandardError
134
135
  nil
135
136
  end
@@ -137,7 +138,7 @@ module SemanticLogger
137
138
  @thread = nil
138
139
  # This block may be called after the file handles have been released by Ruby
139
140
  begin
140
- logger.trace('Async: Thread has stopped')
141
+ logger.trace("Async: Thread has stopped")
141
142
  rescue StandardError
142
143
  nil
143
144
  end
@@ -159,7 +160,7 @@ module SemanticLogger
159
160
  break unless process_message(message)
160
161
  end
161
162
  end
162
- logger.trace 'Async: Queue Closed'
163
+ logger.trace "Async: Queue Closed"
163
164
  end
164
165
 
165
166
  # Returns false when message processing should be stopped
@@ -1,4 +1,4 @@
1
- require 'concurrent'
1
+ require "concurrent"
2
2
 
3
3
  module SemanticLogger
4
4
  module Appender
@@ -42,7 +42,9 @@ module SemanticLogger
42
42
  lag_threshold_s: lag_threshold_s
43
43
  )
44
44
 
45
- raise(ArgumentError, "#{appender.class.name} does not support batching. It must implement #batch") unless appender.respond_to?(:batch)
45
+ return if appender.respond_to?(:batch)
46
+
47
+ raise(ArgumentError, "#{appender.class.name} does not support batching. It must implement #batch")
46
48
  end
47
49
 
48
50
  # Add log message for processing.
@@ -62,6 +64,7 @@ module SemanticLogger
62
64
  signal.wait(batch_seconds)
63
65
 
64
66
  logs = []
67
+ messages = []
65
68
  first = true
66
69
  message_count = queue.length
67
70
  message_count.times do
@@ -74,10 +77,11 @@ module SemanticLogger
74
77
  first = false
75
78
  end
76
79
  else
77
- process_message(message)
80
+ messages << message
78
81
  end
79
82
  end
80
83
  appender.batch(logs) if logs.size.positive?
84
+ messages.each { |message| process_message(message) }
81
85
  signal.reset unless queue.size >= batch_size
82
86
  end
83
87
  end
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'bugsnag'
2
+ require "bugsnag"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem bugsnag is required for logging purposes. Please add the gem "bugsnag" to your Gemfile.')
4
+ raise LoadError, 'Gem bugsnag is required for logging purposes. Please add the gem "bugsnag" to your Gemfile.'
5
5
  end
6
6
 
7
7
  # Send log messages to Bugsnag
@@ -30,7 +30,7 @@ module SemanticLogger
30
30
  # Proc: Only include log messages where the supplied Proc returns true
31
31
  # The Proc must return true or false.
32
32
  def initialize(level: :error, **args, &block)
33
- raise 'Bugsnag only supports :info, :warn, or :error log levels' unless %i[info warn error fatal].include?(level)
33
+ raise "Bugsnag only supports :info, :warn, or :error log levels" unless %i[info warn error fatal].include?(level)
34
34
 
35
35
  # Replace the Bugsnag logger so that we can identify its log messages and not forward them to Bugsnag
36
36
  ::Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] }
@@ -40,48 +40,61 @@ module SemanticLogger
40
40
 
41
41
  # Returns [Hash] of parameters to send to Bugsnag.
42
42
  def call(log, logger)
43
- h = SemanticLogger::Formatters::Raw.new.call(log, logger)
44
- h[:severity] = log_level(log)
45
- h.delete(:message) if h[:exception] && (h[:message] == h[:exception][:message])
46
- h.delete(:time)
47
- h.delete(:exception)
48
- h
43
+ hash = SemanticLogger::Formatters::Raw.new.call(log, logger)
44
+ hash.delete(:message) if hash[:exception] && (hash[:message] == hash[:exception][:message])
45
+ hash.delete(:time)
46
+ hash.delete(:level_index)
47
+ hash.delete(:exception)
48
+ hash[:file] = "#{hash[:file]}:#{hash.delete(:line)}" if hash.key?(:file)
49
+ hash
49
50
  end
50
51
 
51
- # Send an error notification to Bugsnag
52
52
  def log(log)
53
53
  # Ignore logs coming from Bugsnag itself
54
- return false if log.name == 'Bugsnag'
54
+ return false if log.name == "Bugsnag"
55
55
 
56
56
  # Send error messages as Runtime exceptions
57
- exception =
58
- if log.exception
59
- # Manually constructed Exception, without a backtrace.
60
- log.exception.set_backtrace(log.backtrace) if !log.exception.backtrace && log.backtrace
61
- log.exception
62
- else
63
- error = RuntimeError.new(log.message)
64
- error.set_backtrace(log.backtrace) if log.backtrace
65
- error
66
- end
67
-
68
- # For more documentation on the Bugsnag.notify method see:
69
- # https://bugsnag.com/docs/notifiers/ruby#sending-handled-exceptions
70
- ::Bugsnag.notify(exception, formatter.call(log, self))
57
+ exception = extract_exception(log)
58
+ hash = formatter.call(log, self)
59
+ bugsnag_notify(exception, hash, log_level(log.level))
71
60
  true
72
61
  end
73
62
 
74
63
  private
75
64
 
65
+ def bugsnag_notify(exception, hash, level)
66
+ if ::Bugsnag::VERSION.to_i >= 6
67
+ ::Bugsnag.notify(exception) do |report|
68
+ report.severity = level
69
+ hash.each_pair { |key, value| report.add_tab(key, value) }
70
+ end
71
+ else
72
+ hash[:severity] = level
73
+ ::Bugsnag.notify(exception, hash)
74
+ end
75
+ end
76
+
77
+ def extract_exception(log)
78
+ if log.exception
79
+ # Manually constructed Exception, without a backtrace.
80
+ log.exception.set_backtrace(log.backtrace) if !log.exception.backtrace && log.backtrace
81
+ return log.exception
82
+ end
83
+
84
+ error = RuntimeError.new(log.message)
85
+ error.set_backtrace(log.backtrace) if log.backtrace
86
+ error
87
+ end
88
+
76
89
  # Bugsnag supports: error, warning or info
77
- def log_level(log)
78
- case log.level
90
+ def log_level(level)
91
+ case level
79
92
  when :error, :fatal
80
- 'error'
93
+ "error"
81
94
  when :warn
82
- 'warning'
95
+ "warning"
83
96
  else
84
- 'info'
97
+ "info"
85
98
  end
86
99
  end
87
100
  end
@@ -1,10 +1,11 @@
1
1
  begin
2
- require 'elasticsearch'
2
+ require "elasticsearch"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.')
4
+ raise LoadError,
5
+ 'Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.'
5
6
  end
6
7
 
7
- require 'date'
8
+ require "date"
8
9
 
9
10
  # Forward all log messages to Elasticsearch.
10
11
  #
@@ -17,7 +18,8 @@ require 'date'
17
18
  module SemanticLogger
18
19
  module Appender
19
20
  class Elasticsearch < SemanticLogger::Subscriber
20
- attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size, :elasticsearch_args
21
+ attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
22
+ :elasticsearch_args
21
23
 
22
24
  # Create Elasticsearch appender over persistent HTTP(S)
23
25
  #
@@ -123,17 +125,17 @@ module SemanticLogger
123
125
  # send_get_body_as [String]
124
126
  # Specify the HTTP method to use for GET requests with a body.
125
127
  # Default: 'GET'
126
- def initialize(url: 'http://localhost:9200',
127
- index: 'semantic_logger',
128
- date_pattern: '%Y.%m.%d',
129
- type: 'log',
128
+ def initialize(url: "http://localhost:9200",
129
+ index: "semantic_logger",
130
+ date_pattern: "%Y.%m.%d",
131
+ type: "log",
130
132
  level: nil,
131
133
  formatter: nil,
132
134
  filter: nil,
133
135
  application: nil,
134
136
  environment: nil,
135
137
  host: nil,
136
- metrics: false,
138
+ data_stream: false,
137
139
  **elasticsearch_args,
138
140
  &block)
139
141
 
@@ -144,6 +146,7 @@ module SemanticLogger
144
146
  @elasticsearch_args = elasticsearch_args.dup
145
147
  @elasticsearch_args[:url] = url if url && !elasticsearch_args[:hosts]
146
148
  @elasticsearch_args[:logger] = logger
149
+ @data_stream = data_stream
147
150
 
148
151
  super(level: level, formatter: formatter, filter: filter, application: application, environment: environment, host: host, metrics: false, &block)
149
152
  reopen
@@ -173,20 +176,35 @@ module SemanticLogger
173
176
  private
174
177
 
175
178
  def write_to_elasticsearch(messages)
176
- bulk_result = @client.bulk(body: messages)
177
- return unless bulk_result['errors']
179
+ bulk_result = if @data_stream
180
+ @client.bulk(index: index, body: messages)
181
+ else
182
+ @client.bulk(body: messages)
183
+ end
178
184
 
179
- failed = bulk_result['items'].reject { |x| x['status'] == 201 }
185
+ return unless bulk_result["errors"]
186
+
187
+ failed = bulk_result["items"].reject { |x| x["status"] == 201 }
180
188
  logger.error("ElasticSearch: Write failed. Messages discarded. : #{failed}")
181
189
  end
182
190
 
183
191
  def bulk_index(log)
184
192
  expanded_index_name = log.time.strftime("#{index}-#{date_pattern}")
185
- {'index' => {'_index' => expanded_index_name, '_type' => type}}
193
+ if @data_stream
194
+ {"create" => {}}
195
+ else
196
+ {"index" => {"_index" => expanded_index_name, "_type" => type}}
197
+ end
186
198
  end
187
199
 
188
200
  def default_formatter
189
- SemanticLogger::Formatters::Raw.new(time_format: :iso_8601, time_key: :timestamp)
201
+ time_key = if @data_stream
202
+ "@timestamp"
203
+ else
204
+ :timestamp
205
+ end
206
+
207
+ SemanticLogger::Formatters::Raw.new(time_format: :iso_8601, time_key: time_key)
190
208
  end
191
209
  end
192
210
  end
@@ -1,4 +1,4 @@
1
- require 'date'
1
+ require "date"
2
2
  # Forward all log messages to Elasticsearch one at a time via a HTTP post.
3
3
  #
4
4
  # Note:
@@ -50,9 +50,9 @@ module SemanticLogger
50
50
  # application: [String]
51
51
  # Name of this application to appear in log messages.
52
52
  # Default: SemanticLogger.application
53
- def initialize(index: 'semantic_logger',
54
- type: 'log',
55
- url: 'http://localhost:9200',
53
+ def initialize(index: "semantic_logger",
54
+ type: "log",
55
+ url: "http://localhost:9200",
56
56
  **http_args,
57
57
  &block)
58
58