logstash-output-loki 1.0.1 → 1.0.3
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 +4 -4
- data/README.md +6 -4
- data/lib/logstash/outputs/loki.rb +72 -47
- data/logstash-output-loki.gemspec +2 -3
- data/spec/outputs/loki_spec.rb +9 -8
- metadata +9 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a76f3826de04d39e57f06c522125adfc150e1b9c44dee915cb5a220e829b5ae6
|
4
|
+
data.tar.gz: d4f881165097a6c04dcef15eca32f3570f0d35453a16713e5da1a50e022876d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 706a86a1852e2b2e97bbd340904b1a0a72751beca4ca4257bfbd66683e0c3a7fe5a54d273666c2da98947b84270b4e9544fe36b6e1742877ccffcbf67fe090bc
|
7
|
+
data.tar.gz: 5710b40ac392fa8e82c29343f22b444ce12284023497da3d0cb9c28049b81811ece3bcf431e5b948b7c60dd29c941dcd3c508289fc9a2d49faf5331eda893f69
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Contributing to Loki Logstash Output Plugin
|
2
2
|
|
3
|
-
For information about
|
3
|
+
For information about how to use this plugin see this [documentation](../../docs/sources/clients/logstash/_index.md).
|
4
4
|
|
5
5
|
## Install dependencies
|
6
6
|
|
7
|
-
First
|
7
|
+
First, make sure you have JDK version `8` or `11` installed and you have set the `JAVA_HOME` environment variable.
|
8
|
+
|
9
|
+
You need to setup JRuby environment to build this plugin. Refer https://github.com/rbenv/rbenv for setting up your rbenv environment.
|
8
10
|
|
9
11
|
After setting up `rbenv`. Install JRuby
|
10
12
|
|
@@ -20,7 +22,7 @@ ruby --version
|
|
20
22
|
jruby 9.2.10
|
21
23
|
```
|
22
24
|
|
23
|
-
You should
|
25
|
+
You should make sure you are running `jruby` and not `ruby`. If the command `ruby --version` still shows `ruby` and not `jruby`, check that PATH contains `$HOME/.rbenv/shims` and `$HOME/.rbenv/bin`. Also verify that you have this in your bash profile:
|
24
26
|
|
25
27
|
```bash
|
26
28
|
export PATH="$HOME/.rbenv/bin:$PATH"
|
@@ -32,7 +34,7 @@ Then install bundler
|
|
32
34
|
|
33
35
|
Follow those instructions to [install logstash](https://www.elastic.co/guide/en/logstash/current/installing-logstash.html) before moving to the next section.
|
34
36
|
|
35
|
-
##
|
37
|
+
## Build and test the plugin
|
36
38
|
|
37
39
|
### Install required packages
|
38
40
|
|
@@ -4,7 +4,6 @@ require "logstash/outputs/loki/entry"
|
|
4
4
|
require "logstash/outputs/loki/batch"
|
5
5
|
require "logstash/namespace"
|
6
6
|
require 'net/http'
|
7
|
-
require 'concurrent-edge'
|
8
7
|
require 'time'
|
9
8
|
require 'uri'
|
10
9
|
require 'json'
|
@@ -30,6 +29,9 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
30
29
|
## 'TLS'
|
31
30
|
config :ca_cert, :validate => :path, :required => false
|
32
31
|
|
32
|
+
## 'Disable server certificate verification'
|
33
|
+
config :insecure_skip_verify, :validate => :boolean, :default => false, :required => false
|
34
|
+
|
33
35
|
## 'Loki Tenant ID'
|
34
36
|
config :tenant_id, :validate => :string, :required => false
|
35
37
|
|
@@ -45,8 +47,8 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
45
47
|
## 'Backoff configuration. Initial backoff time between retries. Default 1s'
|
46
48
|
config :min_delay, :validate => :number, :default => 1, :required => false
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
+
## 'Backoff configuration. Maximum backoff time between retries. Default 300s'
|
51
|
+
config :max_delay, :validate => :number, :default => 300, :required => false
|
50
52
|
|
51
53
|
## 'Backoff configuration. Maximum number of retries to do'
|
52
54
|
config :retries, :validate => :number, :default => 10, :required => false
|
@@ -65,10 +67,10 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
65
67
|
|
66
68
|
@logger.info("Loki output plugin", :class => self.class.name)
|
67
69
|
|
68
|
-
# initialize
|
69
|
-
@
|
70
|
-
@
|
71
|
-
@stop =
|
70
|
+
# initialize Queue and Mutex
|
71
|
+
@entries = Queue.new
|
72
|
+
@mutex = Mutex.new
|
73
|
+
@stop = false
|
72
74
|
|
73
75
|
# create nil batch object.
|
74
76
|
@batch = nil
|
@@ -79,7 +81,52 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
79
81
|
validate_ssl_key
|
80
82
|
end
|
81
83
|
|
82
|
-
|
84
|
+
# start batch_max_wait and batch_max_size threads
|
85
|
+
@batch_wait_thread = Thread.new{max_batch_wait()}
|
86
|
+
@batch_size_thread = Thread.new{max_batch_size()}
|
87
|
+
end
|
88
|
+
|
89
|
+
def max_batch_size
|
90
|
+
loop do
|
91
|
+
@mutex.synchronize do
|
92
|
+
return if @stop
|
93
|
+
end
|
94
|
+
|
95
|
+
e = @entries.deq
|
96
|
+
return if e.nil?
|
97
|
+
|
98
|
+
@mutex.synchronize do
|
99
|
+
if !add_entry_to_batch(e)
|
100
|
+
@logger.debug("Max batch_size is reached. Sending batch to loki")
|
101
|
+
send(@batch)
|
102
|
+
@batch = Batch.new(e)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def max_batch_wait
|
109
|
+
# minimum wait frequency is 10 milliseconds
|
110
|
+
min_wait_checkfrequency = 1/100
|
111
|
+
max_wait_checkfrequency = @batch_wait
|
112
|
+
if max_wait_checkfrequency < min_wait_checkfrequency
|
113
|
+
max_wait_checkfrequency = min_wait_checkfrequency
|
114
|
+
end
|
115
|
+
|
116
|
+
loop do
|
117
|
+
@mutex.synchronize do
|
118
|
+
return if @stop
|
119
|
+
end
|
120
|
+
|
121
|
+
sleep(max_wait_checkfrequency)
|
122
|
+
if is_batch_expired
|
123
|
+
@mutex.synchronize do
|
124
|
+
@logger.debug("Max batch_wait time is reached. Sending batch to loki")
|
125
|
+
send(@batch)
|
126
|
+
@batch = nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
83
130
|
end
|
84
131
|
|
85
132
|
def ssl_cert?
|
@@ -102,6 +149,13 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
102
149
|
use_ssl: uri.scheme == 'https'
|
103
150
|
}
|
104
151
|
|
152
|
+
# disable server certificate verification
|
153
|
+
if @insecure_skip_verify
|
154
|
+
opts = opts.merge(
|
155
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
105
159
|
if !@cert.nil? && !@key.nil?
|
106
160
|
opts = opts.merge(
|
107
161
|
verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
@@ -118,39 +172,7 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
118
172
|
opts
|
119
173
|
end
|
120
174
|
|
121
|
-
|
122
|
-
min_wait_checkfrequency = 1/100 #1 millisecond
|
123
|
-
max_wait_checkfrequency = @batch_wait / 10
|
124
|
-
if max_wait_checkfrequency < min_wait_checkfrequency
|
125
|
-
max_wait_checkfrequency = min_wait_checkfrequency
|
126
|
-
end
|
127
|
-
|
128
|
-
@max_wait_check = Concurrent::Channel.tick(max_wait_checkfrequency)
|
129
|
-
loop do
|
130
|
-
Concurrent::Channel.select do |s|
|
131
|
-
s.take(@stop) {
|
132
|
-
return
|
133
|
-
}
|
134
|
-
s.take(@entries) { |e|
|
135
|
-
if !add_entry_to_batch(e)
|
136
|
-
@logger.debug("Max batch_size is reached. Sending batch to loki")
|
137
|
-
send(@batch)
|
138
|
-
@batch = Batch.new(e)
|
139
|
-
end
|
140
|
-
}
|
141
|
-
s.take(@max_wait_check) {
|
142
|
-
# Send batch if max wait time has been reached
|
143
|
-
if is_batch_expired
|
144
|
-
@logger.debug("Max batch_wait time is reached. Sending batch to loki")
|
145
|
-
send(@batch)
|
146
|
-
@batch = nil
|
147
|
-
end
|
148
|
-
}
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# add an entry to the current batch return false if the batch is full
|
175
|
+
# Add an entry to the current batch returns false if the batch is full
|
154
176
|
# and the entry can't be added.
|
155
177
|
def add_entry_to_batch(e)
|
156
178
|
line = e.entry['line']
|
@@ -181,8 +203,11 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
181
203
|
|
182
204
|
def close
|
183
205
|
@entries.close
|
184
|
-
@
|
185
|
-
|
206
|
+
@mutex.synchronize do
|
207
|
+
@stop = true
|
208
|
+
end
|
209
|
+
@batch_wait_thread.join
|
210
|
+
@batch_size_thread.join
|
186
211
|
|
187
212
|
# if by any chance we still have a forming batch, we need to send it.
|
188
213
|
send(@batch) if !@batch.nil?
|
@@ -222,13 +247,13 @@ class LogStash::Outputs::Loki < LogStash::Outputs::Base
|
|
222
247
|
raise StandardError.new res
|
223
248
|
rescue StandardError => e
|
224
249
|
retry_count += 1
|
225
|
-
@logger.warn("Failed to send batch attempt: #{retry_count}/#{@retries}", :error_inspect => e.inspect, :error => e)
|
250
|
+
@logger.warn("Failed to send batch, attempt: #{retry_count}/#{@retries}", :error_inspect => e.inspect, :error => e)
|
226
251
|
if retry_count < @retries
|
227
252
|
sleep delay
|
228
|
-
if
|
229
|
-
delay = delay
|
230
|
-
else
|
253
|
+
if delay * 2 <= @max_delay
|
231
254
|
delay = delay * 2
|
255
|
+
else
|
256
|
+
delay = @max_delay
|
232
257
|
end
|
233
258
|
retry
|
234
259
|
else
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name
|
3
|
-
s.version
|
2
|
+
s.name = 'logstash-output-loki'
|
3
|
+
s.version = '1.0.3'
|
4
4
|
s.authors = ['Aditya C S','Cyril Tovena']
|
5
5
|
s.email = ['aditya.gnu@gmail.com','cyril.tovena@grafana.com']
|
6
6
|
|
@@ -22,6 +22,5 @@ Gem::Specification.new do |s|
|
|
22
22
|
#
|
23
23
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
24
|
s.add_runtime_dependency "logstash-codec-plain", "3.0.6"
|
25
|
-
s.add_runtime_dependency "concurrent-ruby-edge", "0.6.0"
|
26
25
|
s.add_development_dependency 'logstash-devutils', "2.0.2"
|
27
26
|
end
|
data/spec/outputs/loki_spec.rb
CHANGED
@@ -95,7 +95,7 @@ describe LogStash::Outputs::Loki do
|
|
95
95
|
it 'should send entry if batch size reached with no tenant' do
|
96
96
|
loki = LogStash::Outputs::Loki.new(simple_loki_config.merge!({'batch_wait'=>0.5,'batch_size'=>10}))
|
97
97
|
loki.register
|
98
|
-
sent =
|
98
|
+
sent = Queue.new
|
99
99
|
allow(loki).to receive(:send) do |batch|
|
100
100
|
Thread.new do
|
101
101
|
sent << batch
|
@@ -103,14 +103,14 @@ describe LogStash::Outputs::Loki do
|
|
103
103
|
end
|
104
104
|
loki.receive(event)
|
105
105
|
loki.receive(event)
|
106
|
+
sent.deq
|
107
|
+
sent.deq
|
106
108
|
loki.close
|
107
|
-
~sent
|
108
|
-
~sent
|
109
109
|
end
|
110
110
|
it 'should send entry while closing' do
|
111
111
|
loki = LogStash::Outputs::Loki.new(simple_loki_config.merge!({'batch_wait'=>10,'batch_size'=>10}))
|
112
112
|
loki.register
|
113
|
-
sent =
|
113
|
+
sent = Queue.new
|
114
114
|
allow(loki).to receive(:send) do | batch|
|
115
115
|
Thread.new do
|
116
116
|
sent << batch
|
@@ -118,20 +118,21 @@ describe LogStash::Outputs::Loki do
|
|
118
118
|
end
|
119
119
|
loki.receive(event)
|
120
120
|
loki.close
|
121
|
-
|
121
|
+
sent.deq
|
122
122
|
end
|
123
123
|
it 'should send entry when batch is expiring' do
|
124
124
|
loki = LogStash::Outputs::Loki.new(simple_loki_config.merge!({'batch_wait'=>0.5,'batch_size'=>10}))
|
125
125
|
loki.register
|
126
|
-
sent =
|
126
|
+
sent = Queue.new
|
127
127
|
allow(loki).to receive(:send) do | batch|
|
128
128
|
Thread.new do
|
129
129
|
sent << batch
|
130
130
|
end
|
131
131
|
end
|
132
132
|
loki.receive(event)
|
133
|
-
|
134
|
-
|
133
|
+
sent.deq
|
134
|
+
sleep(0.01) # Adding a minimal sleep. In few cases @batch=nil might happen after evaluating for nil
|
135
|
+
expect(loki.batch).to be_nil
|
135
136
|
loki.close
|
136
137
|
end
|
137
138
|
end
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-loki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aditya C S
|
8
8
|
- Cyril Tovena
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-11-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
+
name: logstash-core-plugin-api
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
18
|
- - ">="
|
@@ -20,7 +21,6 @@ dependencies:
|
|
20
21
|
- - "<="
|
21
22
|
- !ruby/object:Gem::Version
|
22
23
|
version: '2.99'
|
23
|
-
name: logstash-core-plugin-api
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -32,12 +32,12 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '2.99'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
+
name: logstash-codec-plain
|
35
36
|
requirement: !ruby/object:Gem::Requirement
|
36
37
|
requirements:
|
37
38
|
- - '='
|
38
39
|
- !ruby/object:Gem::Version
|
39
40
|
version: 3.0.6
|
40
|
-
name: logstash-codec-plain
|
41
41
|
type: :runtime
|
42
42
|
prerelease: false
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -46,26 +46,12 @@ dependencies:
|
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 3.0.6
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
|
50
|
-
requirements:
|
51
|
-
- - '='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 0.6.0
|
54
|
-
name: concurrent-ruby-edge
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.6.0
|
62
|
-
- !ruby/object:Gem::Dependency
|
49
|
+
name: logstash-devutils
|
63
50
|
requirement: !ruby/object:Gem::Requirement
|
64
51
|
requirements:
|
65
52
|
- - '='
|
66
53
|
- !ruby/object:Gem::Version
|
67
54
|
version: 2.0.2
|
68
|
-
name: logstash-devutils
|
69
55
|
type: :development
|
70
56
|
prerelease: false
|
71
57
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -95,7 +81,7 @@ licenses:
|
|
95
81
|
metadata:
|
96
82
|
logstash_plugin: 'true'
|
97
83
|
logstash_group: output
|
98
|
-
post_install_message:
|
84
|
+
post_install_message:
|
99
85
|
rdoc_options: []
|
100
86
|
require_paths:
|
101
87
|
- lib
|
@@ -110,8 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
96
|
- !ruby/object:Gem::Version
|
111
97
|
version: '0'
|
112
98
|
requirements: []
|
113
|
-
rubygems_version: 3.0.
|
114
|
-
signing_key:
|
99
|
+
rubygems_version: 3.0.3
|
100
|
+
signing_key:
|
115
101
|
specification_version: 4
|
116
102
|
summary: Output plugin to ship logs to a Grafana Loki server
|
117
103
|
test_files:
|