md-logstasher 1.2.0 → 1.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7c18dc1deb3c464f76519b0d3ee05ba7d53c0f27
4
- data.tar.gz: 2ed90acab2250ff497c14636f0bb45995d83dcd0
2
+ SHA256:
3
+ metadata.gz: 2a3ecf9c0501945ebb201adb054bcb8e419ab6282e4373fcc5f83c141f0fe606
4
+ data.tar.gz: 52acbb7139d4f00775f0ad88115a0237dee699aa8ce42fc8b9c0aabdd9786438
5
5
  SHA512:
6
- metadata.gz: 1aba3381d4c2bcfbc9d1d2d640246098a0a2f676a7675cc8b21997ea09151b1c3c9e1672972a1e771762253532bfc22cf9b647164844d7ac84b3d82b9701dc03
7
- data.tar.gz: 7603f411836c855ec467122d243cd0e430894ccdc53aa8080ad6f064e1df7e6b36addd0f0d4aee9e7fa7bfca9aab0ba3669422c63fc421f772f320e9026b210e
6
+ metadata.gz: 074e9580a2b16e2d9d25c948559a43c74d03ea3de65854b20c36fbaeb2f921d77ea11206533bebe6b9ed490d1ffc5e5f0951db1ed83f9275c5309c39cb9a78b6
7
+ data.tar.gz: 8353c5595d42b6da680afbc7cf4b673bf23b5b2ba9f784e7bb9c1e5b34c5fe0faa3d9ba9c648cd449e50299691a7bb91f69b3ee46458d85f8074558146801c07
@@ -0,0 +1,40 @@
1
+ # simple UDP logger
2
+
3
+ require 'logstasher/device'
4
+ require 'socket'
5
+
6
+
7
+ module LogStasher
8
+ module Device
9
+ class UDP
10
+ include ::LogStasher::Device
11
+
12
+ attr_reader :options, :socket
13
+
14
+ def initialize(options = {})
15
+ @options = default_options.merge(stringify_keys(options))
16
+ @socket = UDPSocket.new
17
+ end
18
+
19
+ def close
20
+ @socket.close
21
+ end
22
+
23
+ def write(log)
24
+ @socket.send(log, 0, options['hostname'], options['port'])
25
+ end
26
+
27
+ private
28
+
29
+ def default_options
30
+ {
31
+ 'hostname' => '127.0.0.1',
32
+ 'port' => 31459,
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+
40
+
@@ -11,6 +11,11 @@ module LogStasher
11
11
  when "syslog", :syslog then
12
12
  require 'logstasher/device/syslog'
13
13
  ::LogStasher::Device::Syslog.new(config)
14
+ when "udp", :udp then
15
+ require 'logstasher/device/udp'
16
+ ::LogStasher::Device::UDP.new(config)
17
+ when "stdout", :stdout then
18
+ $stdout
14
19
  else
15
20
  fail ArgumentError, "Unknown type: #{type}"
16
21
  end
@@ -21,7 +21,6 @@ module LogStasher
21
21
  payload = event.payload
22
22
  tags = extract_tags(payload)
23
23
  fields = extract_request(payload)
24
-
25
24
  fields.merge! extract_status(payload)
26
25
  fields.merge! runtimes(event)
27
26
  fields.merge! location
@@ -29,9 +28,7 @@ module LogStasher
29
28
  fields.merge! extract_parameters(payload)
30
29
  fields.merge! appended_fields
31
30
 
32
- event = LogStash::Event.new(fields.merge('tags' => tags))
33
-
34
- LogStasher.logger << event.to_json + "\n"
31
+ LogStasher.log_as_json(fields.merge('tags' => tags), :as_logstash_event => true)
35
32
  end
36
33
 
37
34
  def redirect_to(event)
@@ -87,7 +84,6 @@ module LogStasher
87
84
  def extract_parameters(payload)
88
85
  if LogStasher.include_parameters?
89
86
  external_params = payload[:params].except(*INTERNAL_PARAMS)
90
-
91
87
  if LogStasher.serialize_parameters?
92
88
  { :params => JSON.generate(external_params) }
93
89
  else
@@ -8,6 +8,7 @@ module LogStasher
8
8
  config.logstasher.logger = nil
9
9
  config.logstasher.log_level = ::Logger::INFO
10
10
 
11
+ config.logstasher.metadata = {}
11
12
  config.before_initialize do
12
13
  options = config.logstasher
13
14
 
@@ -17,6 +18,7 @@ module LogStasher
17
18
  ::LogStasher.silence_standard_logging = options.silence_standard_logging
18
19
  ::LogStasher.logger = options.logger || default_logger
19
20
  ::LogStasher.logger.level = options.log_level
21
+ ::LogStasher.metadata = options.metadata
20
22
  end
21
23
 
22
24
  initializer 'logstasher.load' do
@@ -1,3 +1,3 @@
1
1
  module LogStasher
2
- VERSION = "1.2.0"
2
+ VERSION = "1.5.0"
3
3
  end
data/lib/logstasher.rb CHANGED
@@ -8,6 +8,7 @@ module LogStasher
8
8
  attr_writer :include_parameters
9
9
  attr_writer :serialize_parameters
10
10
  attr_writer :silence_standard_logging
11
+ attr_accessor :metadata
11
12
 
12
13
  def append_fields(&block)
13
14
  @append_fields_callback = block
@@ -43,6 +44,22 @@ module LogStasher
43
44
  end
44
45
  end
45
46
 
47
+ def log_as_json(payload, as_logstash_event: false)
48
+ payload = payload.dup
49
+ payload.merge!(:metadata => metadata) if !metadata&.empty? && payload.is_a?(::Hash)
50
+
51
+ # Wrap the hash in a logstash event if the caller wishes for a specific
52
+ # formatting applied to the hash. This is used by log subscriber, for
53
+ # example.
54
+ json_payload = if as_logstash_event
55
+ ::LogStash::Event.new(payload).to_json
56
+ else
57
+ payload.to_json
58
+ end
59
+
60
+ logger << json_payload + $INPUT_RECORD_SEPARATOR
61
+ end
62
+
46
63
  def logger
47
64
  @logger ||= initialize_logger
48
65
  end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ require 'logstasher/device/udp'
4
+
5
+ describe LogStasher::Device::UDP do
6
+
7
+ let(:default_options) {{
8
+ 'hostname' => '127.0.0.1',
9
+ 'port' => 31459
10
+ }}
11
+
12
+ it 'has default options' do
13
+ device = LogStasher::Device::UDP.new
14
+ expect(device.options).to eq(default_options)
15
+ end
16
+
17
+ it 'closes the udp socket on #close' do
18
+ device = LogStasher::Device::UDP.new
19
+ expect(device.socket).to receive(:close)
20
+ device.close
21
+ end
22
+
23
+ it 'works as a logger device' do
24
+ device = LogStasher::Device::UDP.new
25
+ expect(device).to receive(:write).with('foo')
26
+ logger = Logger.new(device)
27
+ logger << 'foo'
28
+ end
29
+
30
+ describe '#write' do
31
+ subject { LogStasher::Device::UDP.new }
32
+ it 'writes the log to the the socket' do
33
+ expect(subject.socket).to receive(:send).with('a log', 0, default_options['hostname'], default_options['port'])
34
+ subject.write('a log')
35
+ end
36
+ end
37
+ end
@@ -3,6 +3,7 @@ require "spec_helper"
3
3
  require "logstasher/device"
4
4
  require "logstasher/device/redis"
5
5
  require "logstasher/device/syslog"
6
+ require "logstasher/device/udp"
6
7
 
7
8
  describe LogStasher::Device do
8
9
  describe ".factory" do
@@ -47,7 +48,21 @@ describe LogStasher::Device do
47
48
  device = ::LogStasher::Device.factory(:type => "syslog")
48
49
  expect(device).to be_a_kind_of(::LogStasher::Device::Syslog)
49
50
  end
51
+
52
+ it "can create udp devices" do
53
+ expect(
54
+ ::LogStasher::Device
55
+ ).to receive(:require).with("logstasher/device/udp")
50
56
 
57
+ device = ::LogStasher::Device.factory(:type => "udp")
58
+ expect(device).to be_a_kind_of(::LogStasher::Device::UDP)
59
+ end
60
+
61
+ it "can create stdout devices" do
62
+ device = ::LogStasher::Device.factory(:type => "stdout")
63
+ expect(device).to eq $stdout
64
+ end
65
+
51
66
  it "fails to create unknown devices" do
52
67
  expect {
53
68
  ::LogStasher::Device.factory(:type => "unknown")
@@ -10,6 +10,12 @@ class MockController
10
10
  end
11
11
 
12
12
  class MockRequest
13
+ attr_accessor :env
14
+
15
+ def initialize
16
+ @env = { 'action_dispatch.request_id' => 1 }
17
+ end
18
+
13
19
  def remote_ip
14
20
  '127.0.0.1'
15
21
  end
@@ -19,6 +25,7 @@ describe LogStasher::LogSubscriber do
19
25
  subject { described_class.new }
20
26
 
21
27
  let(:logger) { ::Logger.new('/dev/null') }
28
+
22
29
  let(:mock_controller) { MockController.new }
23
30
  let(:mock_request) { MockRequest.new }
24
31
  let(:context) {{ :controller => mock_controller, :request => mock_request }}
@@ -46,9 +53,13 @@ describe LogStasher::LogSubscriber do
46
53
  :path => '/users/1',
47
54
  :status => 200
48
55
  }}
56
+ let(:data) { { "namespace" => "test", "appversion" => "v1" } }
49
57
 
50
58
  let(:event) { double(:payload => payload, :duration => duration) }
51
59
 
60
+ before { ::LogStasher.metadata = data }
61
+ after { ::LogStasher.metadata = {} }
62
+
52
63
  it 'logs the event in logstash format' do
53
64
  expect(logger).to receive(:<<) do |json|
54
65
  expect(JSON.parse(json)).to eq({
@@ -64,7 +75,9 @@ describe LogStasher::LogSubscriber do
64
75
  'path' => payload[:path],
65
76
  'route' => "#{payload[:controller]}##{payload[:action]}",
66
77
  'status' => payload[:status],
67
- 'runtime' => { 'total' => duration }
78
+ 'runtime' => { 'total' => duration },
79
+ 'request_id' => 1,
80
+ 'metadata' => data
68
81
  })
69
82
  end
70
83
 
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe ::LogStasher do
4
+ describe "#log_as_json" do
5
+ it "calls the logger with the payload" do
6
+ expect(::LogStasher.logger).to receive(:<<) do |json|
7
+ expect(::JSON.parse(json)).to eq("yolo" => "brolo")
8
+ end
9
+
10
+ ::LogStasher.log_as_json(:yolo => :brolo)
11
+ end
12
+
13
+ context "with event" do
14
+ it "calls logger with a logstash event" do
15
+ expect(::LogStasher.logger).to receive(:<<) do |json|
16
+ payload = ::JSON.parse(json)
17
+
18
+ expect(payload["@timestamp"]).to_not be_nil
19
+ expect(payload["@version"]).to eq("1")
20
+ expect(payload["yolo"]).to eq("brolo")
21
+ end
22
+
23
+ ::LogStasher.log_as_json({:yolo => :brolo}, :as_logstash_event => true)
24
+ end
25
+ end
26
+
27
+ context "with metadata" do
28
+ before { ::LogStasher.metadata = { :namespace => :cooldude } }
29
+ after { ::LogStasher.metadata = {} }
30
+
31
+ it "calls logger with the metadata" do
32
+ expect(::LogStasher.logger).to receive(:<<) do |json|
33
+ expect(::JSON.parse(json)).to eq("yolo" => "brolo", "metadata" => { "namespace" => "cooldude" })
34
+ end
35
+
36
+ ::LogStasher.log_as_json(:yolo => :brolo)
37
+ end
38
+
39
+ it "does not merge metadata on an array" do
40
+ expect(::LogStasher.logger).to receive(:<<) do |json|
41
+ expect(::JSON.parse(json)).to eq([{ "yolo" => "brolo" }])
42
+ end
43
+
44
+ ::LogStasher.log_as_json([{:yolo => :brolo}])
45
+ end
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: md-logstasher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Devin Christensen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-04 00:00:00.000000000 Z
11
+ date: 2022-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-event
@@ -85,6 +85,7 @@ files:
85
85
  - lib/logstasher/device.rb
86
86
  - lib/logstasher/device/redis.rb
87
87
  - lib/logstasher/device/syslog.rb
88
+ - lib/logstasher/device/udp.rb
88
89
  - lib/logstasher/log_subscriber.rb
89
90
  - lib/logstasher/railtie.rb
90
91
  - lib/logstasher/silent_logger.rb
@@ -96,8 +97,10 @@ files:
96
97
  - logstasher.gemspec
97
98
  - spec/lib/logstasher/device/redis_spec.rb
98
99
  - spec/lib/logstasher/device/syslog_spec.rb
100
+ - spec/lib/logstasher/device/udp_spec.rb
99
101
  - spec/lib/logstasher/device_spec.rb
100
102
  - spec/lib/logstasher/log_subscriber_spec.rb
103
+ - spec/lib/logstasher/logstasher_spec.rb
101
104
  - spec/lib/logstasher/railtie_spec.rb
102
105
  - spec/lib/logstasher_spec.rb
103
106
  - spec/spec_helper.rb
@@ -105,7 +108,7 @@ homepage: https://github.com/moneydesktop/logstasher
105
108
  licenses:
106
109
  - MIT
107
110
  metadata: {}
108
- post_install_message:
111
+ post_install_message:
109
112
  rdoc_options: []
110
113
  require_paths:
111
114
  - lib
@@ -120,16 +123,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
123
  - !ruby/object:Gem::Version
121
124
  version: '0'
122
125
  requirements: []
123
- rubyforge_project:
124
- rubygems_version: 2.6.11
125
- signing_key:
126
+ rubygems_version: 3.2.28
127
+ signing_key:
126
128
  specification_version: 4
127
129
  summary: Awesome rails logs
128
130
  test_files:
129
131
  - spec/lib/logstasher/device/redis_spec.rb
130
132
  - spec/lib/logstasher/device/syslog_spec.rb
133
+ - spec/lib/logstasher/device/udp_spec.rb
131
134
  - spec/lib/logstasher/device_spec.rb
132
135
  - spec/lib/logstasher/log_subscriber_spec.rb
136
+ - spec/lib/logstasher/logstasher_spec.rb
133
137
  - spec/lib/logstasher/railtie_spec.rb
134
138
  - spec/lib/logstasher_spec.rb
135
139
  - spec/spec_helper.rb