md-logstasher 1.2.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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