fluent-plugin-protobuf-http 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +48 -0
- data/.rubocop.yml +19 -0
- data/Gemfile +2 -0
- data/README.md +170 -91
- data/Rakefile +2 -0
- data/fluent-plugin-protobuf-http.gemspec +5 -2
- data/lib/fluent/plugin/in_protobuf_http.rb +21 -23
- data/test/data/log.bin +3 -0
- data/test/data/log.json +1 -0
- data/test/data/logbatch5.bin +12 -0
- data/test/data/protos/log.proto +31 -0
- data/test/helper.rb +10 -5
- data/test/plugin/test_in_protobuf_http.rb +140 -6
- metadata +40 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c12d1da7ec8d1e801e5c9bc01ae3258e4c13ee6d361431721305e8a3778fe0d5
|
4
|
+
data.tar.gz: 2571d4e0c3795fd37c87d07fcbfd80fc7179b7bab0c7d6760c07b3fc7a561e73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfb5aba44bec8f2a9ef10514ef50f5fc2d14084ccd16a8b8bb8d25babc82f351b9bed58ee3c290e00af11fb6dbcb06f4c96d41c342ee67c33fd8b42f6db1399c
|
7
|
+
data.tar.gz: e5e01488511a1509becf3f636e1ab0e653e243dbb44516279555963ed03b09d3333a92d9e8af07a9b9494f75b285adb97e8c7b3ac1f270111b50359054702f80
|
@@ -0,0 +1,48 @@
|
|
1
|
+
name: ci
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
paths-ignore:
|
6
|
+
- '**.md'
|
7
|
+
- '.rubocop.yml'
|
8
|
+
pull_request:
|
9
|
+
paths-ignore:
|
10
|
+
- '**.md'
|
11
|
+
- '.rubocop.yml'
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
run-tests:
|
15
|
+
name: Run tests
|
16
|
+
strategy:
|
17
|
+
matrix:
|
18
|
+
os: [ubuntu-18.04]
|
19
|
+
ruby-version: ['2.5', '2.6', '2.7']
|
20
|
+
|
21
|
+
runs-on: ${{ matrix.os }}
|
22
|
+
|
23
|
+
steps:
|
24
|
+
- uses: actions/checkout@v2
|
25
|
+
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: ${{ matrix.ruby-version }}
|
30
|
+
bundler-cache: true
|
31
|
+
|
32
|
+
- name: Bundle install
|
33
|
+
run: |
|
34
|
+
gem install bundler && \
|
35
|
+
bundle install --jobs 4 --retry 3
|
36
|
+
|
37
|
+
- name: Install protoc
|
38
|
+
run: |
|
39
|
+
mkdir protoc && cd protoc
|
40
|
+
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.0/protoc-3.17.0-linux-x86_64.zip
|
41
|
+
unzip protoc-3.17.0-linux-x86_64.zip
|
42
|
+
chmod +x ./bin/protoc && sudo mv ./bin/protoc /usr/local/bin/protoc
|
43
|
+
sudo mv ./include/* /usr/local/include/
|
44
|
+
cd .. && rm -rf ./protoc
|
45
|
+
protoc --version
|
46
|
+
|
47
|
+
- name: Tests
|
48
|
+
run: bundle exec rake test
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# RuboCop Default Config: https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
NewCops: disable
|
5
|
+
|
6
|
+
Gemspec/RequiredRubyVersion:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Metrics/ClassLength:
|
10
|
+
Enabled: false
|
11
|
+
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Layout/LineLength:
|
19
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,62 +1,79 @@
|
|
1
1
|
# fluent-plugin-protobuf-http
|
2
2
|
|
3
|
+
[![ci](https://github.com/iamazeem/fluent-plugin-protobuf-http/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/iamazeem/fluent-plugin-protobuf-http/actions/workflows/ci.yml)
|
4
|
+
[![License: Apache](https://img.shields.io/badge/license-Apache-blue.svg?style=flat-square)](https://github.com/iamAzeem/fluent-plugin-protobuf-http/blob/master/LICENSE)
|
5
|
+
![GitHub release (latest by date)](https://img.shields.io/github/v/release/iamAzeem/fluent-plugin-protobuf-http?style=flat-square)
|
6
|
+
[![RubyGems Downloads](https://img.shields.io/gem/dt/fluent-plugin-protobuf-http?color=blue&style=flat-square)](https://rubygems.org/gems/fluent-plugin-protobuf-http)
|
7
|
+
|
8
|
+
![Lines of code](https://img.shields.io/tokei/lines/github/iamAzeem/fluent-plugin-protobuf-http?label=LOC&style=flat-square)
|
9
|
+
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/iamAzeem/fluent-plugin-protobuf-http?style=flat-square)
|
10
|
+
![GitHub repo size](https://img.shields.io/github/repo-size/iamAzeem/fluent-plugin-protobuf-http?style=flat-square)
|
11
|
+
|
3
12
|
[Fluentd](https://fluentd.org/) HTTP input plugin for Protocol Buffers.
|
4
13
|
|
5
14
|
## Features
|
6
15
|
|
7
|
-
*
|
8
|
-
*
|
9
|
-
|
10
|
-
*
|
11
|
-
*
|
16
|
+
* Automatic compilation of `.proto` files located in `proto_dir`
|
17
|
+
* Incoming Format: Binary or JSON (`Content-Type`: `application/octet-stream` or
|
18
|
+
`application/json`)
|
19
|
+
* Outgoing Format: Binary or JSON
|
20
|
+
* Single and Batch message support
|
21
|
+
* TLS Support with `<transport>` section and `https://` URL protocol prefix.
|
22
|
+
|
23
|
+
For more details on TLS configuration, see this official
|
24
|
+
[example](https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-server#configuration-example).
|
12
25
|
|
13
26
|
## Installation
|
14
27
|
|
15
28
|
### RubyGems
|
16
29
|
|
17
|
-
```
|
18
|
-
|
30
|
+
```shell
|
31
|
+
gem install fluent-plugin-protobuf-http
|
19
32
|
```
|
20
33
|
|
21
34
|
### Bundler
|
22
35
|
|
23
36
|
Add following line to your Gemfile:
|
37
|
+
|
24
38
|
```ruby
|
25
|
-
gem
|
39
|
+
gem 'fluent-plugin-protobuf-http'
|
26
40
|
```
|
27
41
|
|
28
42
|
And then execute:
|
29
|
-
|
30
|
-
|
43
|
+
|
44
|
+
```shell
|
45
|
+
bundle
|
31
46
|
```
|
32
47
|
|
33
48
|
## Configuration
|
34
49
|
|
35
|
-
*
|
36
|
-
* Default
|
37
|
-
*
|
38
|
-
* Default
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
* Default
|
43
|
-
*
|
44
|
-
*
|
45
|
-
* Default
|
46
|
-
*
|
47
|
-
|
48
|
-
###
|
49
|
-
|
50
|
-
*
|
51
|
-
*
|
52
|
-
* Default
|
53
|
-
*
|
50
|
+
* `bind` (string) (optional): The address to listen to.
|
51
|
+
* Default: `0.0.0.0`
|
52
|
+
* `port` (integer) (optional): The port to listen to.
|
53
|
+
* Default: `8080`
|
54
|
+
* `proto_dir` (string) (required): The directory path that contains the .proto files.
|
55
|
+
* `in_mode` (enum) (optional): The mode of incoming (supported) events.
|
56
|
+
* Modes: `binary`, `json`
|
57
|
+
* Default: `binary`
|
58
|
+
* `out_mode` (enum) (optional): The mode of outgoing (emitted) events.
|
59
|
+
* Modes: `binary`, `json`
|
60
|
+
* Default: `binary`
|
61
|
+
* `tag` (string) (required): The tag for the event.
|
62
|
+
|
63
|
+
### `<transport>` section (optional) (single)
|
64
|
+
|
65
|
+
* `protocol` (enum) (optional):
|
66
|
+
* Protocols: `tcp`, `tls`
|
67
|
+
* Default: `tcp`
|
68
|
+
* For more details, see this official configuration
|
69
|
+
[example](https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-server#configuration-example).
|
54
70
|
|
55
71
|
### Example
|
56
72
|
|
57
|
-
```
|
58
|
-
#
|
59
|
-
#
|
73
|
+
```text
|
74
|
+
# Endpoints:
|
75
|
+
# - Single Message: http://ip:port/<tag>?msgtype=<msgtype>
|
76
|
+
# - Batch Message: http://ip:port/<tag>?msgtype=<batch-msgtype>?batch=true
|
60
77
|
|
61
78
|
<source>
|
62
79
|
@type protobuf_http
|
@@ -74,12 +91,18 @@ $ bundle
|
|
74
91
|
|
75
92
|
## Schemas (`.proto` files)
|
76
93
|
|
77
|
-
The
|
78
|
-
|
79
|
-
|
94
|
+
The prime use-case for this plugin is assumed to be event logging. So, always
|
95
|
+
use self-contained `.proto` file(s) that do not import other `.proto` files. The
|
96
|
+
names e.g. `package`, `message`, etc. must be unique and are treated as
|
97
|
+
case-sensitive.
|
80
98
|
|
81
|
-
Consider this
|
82
|
-
|
99
|
+
Consider this
|
100
|
+
[log.proto](https://github.com/iamAzeem/protobuf-log-sample/blob/master/log.proto)
|
101
|
+
schema from
|
102
|
+
[protobuf-log-sample](https://github.com/iamAzeem/protobuf-log-sample)
|
103
|
+
repository:
|
104
|
+
|
105
|
+
```protobuf
|
83
106
|
syntax = "proto3";
|
84
107
|
|
85
108
|
package service.logging;
|
@@ -108,9 +131,9 @@ message Log {
|
|
108
131
|
}
|
109
132
|
```
|
110
133
|
|
111
|
-
The fully-qualified message type for `Log`
|
112
|
-
|
113
|
-
|
134
|
+
The fully-qualified message type for `Log` is `service.logging.Log`. This
|
135
|
+
message type is used as the value of `msgtype` query parameter in the URL. See
|
136
|
+
URL section below for more on `msgtype`.
|
114
137
|
|
115
138
|
### Single Message
|
116
139
|
|
@@ -118,20 +141,21 @@ The above schema will be used as-is for the single message.
|
|
118
141
|
|
119
142
|
### Batch Message
|
120
143
|
|
121
|
-
For
|
122
|
-
|
144
|
+
For the batch message, the schema must be like this:
|
145
|
+
|
146
|
+
```protobuf
|
123
147
|
message Batch {
|
124
148
|
string type = 1;
|
125
149
|
repeated Log batch = 2;
|
126
150
|
}
|
127
151
|
```
|
128
152
|
|
129
|
-
IMPORTANT:
|
130
|
-
|
131
|
-
You can choose any name for a batch message type.
|
153
|
+
IMPORTANT: The `Batch` message type is part of `log.proto`, it is not a separate
|
154
|
+
file! You can choose any name for a batch message type.
|
132
155
|
|
133
|
-
|
134
|
-
|
156
|
+
Here is the complete `log.proto` file:
|
157
|
+
|
158
|
+
```protobuf
|
135
159
|
syntax = "proto3";
|
136
160
|
|
137
161
|
package service.logging;
|
@@ -165,50 +189,62 @@ message Batch {
|
|
165
189
|
}
|
166
190
|
```
|
167
191
|
|
168
|
-
For batch processing, the plugin looks for special members `type` and `batch`.
|
192
|
+
For batch processing, the plugin looks for special members `type` and `batch`.
|
169
193
|
The `type` will indicate the message type of `batch` i.e. `Log` in this example.
|
170
194
|
|
171
|
-
The type of `Batch` is `service.logging.Batch` and it will be the value of
|
172
|
-
The type of `batch` array is `service.logging.Log`
|
195
|
+
The type of `Batch` is `service.logging.Batch` and it will be the value of
|
196
|
+
`msgtype` in the URL query. The type of `batch` array is `service.logging.Log`
|
197
|
+
and it will be the value of `type`.
|
173
198
|
|
174
|
-
The `google.protobuf.Any` type has not been used deliberately
|
175
|
-
|
176
|
-
|
199
|
+
The `google.protobuf.Any` type has not been used here deliberately. It stores
|
200
|
+
the message type with each message resulting in an increase in size. Refer to
|
201
|
+
[protobuf-repeated-type-vs-any](https://github.com/iamAzeem/protobuf-repeated-type-vs-any)
|
202
|
+
for a simple comparison. With the above approach, the type is stored only once
|
203
|
+
for the whole batch.
|
177
204
|
|
178
205
|
### Endpoint (URL)
|
179
206
|
|
180
207
|
For single message:
|
181
|
-
|
208
|
+
|
209
|
+
```text
|
182
210
|
http://<ip>:<port>/<tag>?msgtype=<fully-qualified-message-type>
|
183
211
|
```
|
184
212
|
|
185
213
|
For batch message:
|
186
|
-
|
214
|
+
|
215
|
+
```text
|
187
216
|
http://<ip>:<port>/<tag>?msgtype=<fully-qualified-message-type-for-batch>&batch=true
|
188
217
|
```
|
189
218
|
|
190
|
-
Without `batch=true` query parameter, the batch will be treated as a single
|
219
|
+
Without `batch=true` query parameter, the batch will be treated as a single
|
220
|
+
message.
|
191
221
|
|
192
|
-
For example, for a log type `service.logging.Log` and its corresponding batch
|
222
|
+
For example, for a log type `service.logging.Log` and its corresponding batch
|
223
|
+
type `service.logging.Batch`, the URLs would be:
|
193
224
|
|
194
|
-
|
195
|
-
|
225
|
+
For single message:
|
226
|
+
|
227
|
+
```text
|
196
228
|
http://localhost:8080/debug.test?msgtype=service.logging.Log
|
197
229
|
```
|
198
230
|
|
199
|
-
|
200
|
-
|
231
|
+
For batch message:
|
232
|
+
|
233
|
+
```text
|
201
234
|
http://localhost:8080/debug.test?msgtype=service.logging.Batch&batch=true
|
202
235
|
```
|
203
236
|
|
204
|
-
**NOTE**: The values of query parameters (`msgtype`, `batch`) are
|
237
|
+
**NOTE**: The values of query parameters (`msgtype`, `batch`) are
|
238
|
+
case-sensitive!
|
205
239
|
|
206
240
|
## Test Use-Case (`curl`)
|
207
241
|
|
208
|
-
For a simple
|
242
|
+
For a simple use-case of incoming HTTP events and their routing to
|
243
|
+
[stdout](https://docs.fluentd.org/output/stdout) may be configured like this:
|
209
244
|
|
210
245
|
`fluent.conf`:
|
211
|
-
|
246
|
+
|
247
|
+
```text
|
212
248
|
<source>
|
213
249
|
@type protobuf_http
|
214
250
|
@id protobuf_http_input
|
@@ -224,24 +260,36 @@ For a simple test use-case of events and their routing to [stdout](https://docs.
|
|
224
260
|
|
225
261
|
<match debug.test>
|
226
262
|
@type stdout
|
227
|
-
@id stdout_output
|
228
263
|
</match>
|
229
264
|
```
|
230
265
|
|
231
266
|
The incoming binary messages will be transformed to JSON for further consumption.
|
232
267
|
|
233
|
-
|
268
|
+
### Single Message
|
269
|
+
|
270
|
+
Test Parameters:
|
234
271
|
|
235
|
-
|
236
|
-
|
272
|
+
| input file | single message type |
|
273
|
+
|:----------:|:---------------------:|
|
274
|
+
| `log.bin` | `service.logging.Log` |
|
237
275
|
|
238
|
-
|
239
|
-
|
240
|
-
|
276
|
+
URL:
|
277
|
+
|
278
|
+
```bash
|
279
|
+
http://localhost:8080/debug.test?msgtype=service.logging.Log
|
241
280
|
```
|
242
281
|
|
243
|
-
`
|
282
|
+
`curl` command:
|
283
|
+
|
284
|
+
```shell
|
285
|
+
curl -X POST -H "Content-Type: application/octet-stream" \
|
286
|
+
--data-binary "@/<path>/log.bin" \
|
287
|
+
"http://localhost:8080/debug.test?msgtype=service.logging.Log"
|
244
288
|
```
|
289
|
+
|
290
|
+
`fluentd` logs (Observe JSON at the end):
|
291
|
+
|
292
|
+
```text
|
245
293
|
2020-06-09 18:53:47 +0500 [info]: #0 [protobuf_http_input] [R] {binary} [127.0.0.1:41222, size: 86 bytes]
|
246
294
|
2020-06-09 18:53:47 +0500 [warn]: #0 [protobuf_http_input] 'batch' not found in 'query_string' [msgtype=service.logging.Log]
|
247
295
|
2020-06-09 18:53:47 +0500 [info]: #0 [protobuf_http_input] [S] {binary} [127.0.0.1:41222, msgtype: service.logging.Log, size: 86 bytes]
|
@@ -249,22 +297,38 @@ $ curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@/<pat
|
|
249
297
|
2020-06-09 18:53:47 +0500 [info]: #0 [protobuf_http_input] [S] {json} [127.0.0.1:41222, msgtype: service.logging.Log, size: 183 bytes]
|
250
298
|
```
|
251
299
|
|
252
|
-
For
|
300
|
+
For sample Single message generation, see
|
301
|
+
[this](https://github.com/iamAzeem/protobuf-log-sample).
|
302
|
+
|
303
|
+
### Batch Message
|
304
|
+
|
305
|
+
Test Parameters:
|
253
306
|
|
254
|
-
|
307
|
+
| input file | batch message type | batch internal type | messages |
|
308
|
+
|:---------------:|:-----------------------:|:---------------------:|:--------:|
|
309
|
+
| `logbatch2.bin` | `service.logging.Batch` | `service.logging.Log` | 2 |
|
310
|
+
| `logbatch5.bin` | `service.logging.Batch` | `service.logging.Log` | 5 |
|
255
311
|
|
256
|
-
|
257
|
-
* data: `logbatch2.bin`, msgtype: `service.logging.Batch`, type: `service.logging.Log` [batch_size: 2 messages]
|
258
|
-
* data: `logbatch5.bin`, msgtype: `service.logging.Batch`, type: `service.logging.Log` [batch_size: 5 messages]
|
312
|
+
URL:
|
259
313
|
|
260
|
-
|
314
|
+
```text
|
315
|
+
http://localhost:8080/debug.test?msgtype=service.logging.Batch&batch=true
|
261
316
|
```
|
262
|
-
|
317
|
+
|
318
|
+
**`logbatch2.bin`**
|
319
|
+
|
320
|
+
`curl` command:
|
321
|
+
|
322
|
+
```shell
|
323
|
+
$ curl -X POST -H "Content-Type: application/octet-stream" \
|
324
|
+
--data-binary "@/<path>/logbatch2.bin" \
|
325
|
+
"http://localhost:8080/debug.test?msgtype=service.logging.Batch&batch=true"
|
263
326
|
{"status":"Batch received! [batch_type: service.logging.Log, batch_size: 2 messages]"}
|
264
327
|
```
|
265
328
|
|
266
|
-
`fluentd`
|
267
|
-
|
329
|
+
`fluentd` logs:
|
330
|
+
|
331
|
+
```text
|
268
332
|
2020-06-09 19:04:13 +0500 [info]: #0 [protobuf_http_input] [R] {binary} [127.0.0.1:41416, size: 207 bytes]
|
269
333
|
2020-06-09 19:04:13 +0500 [info]: #0 [protobuf_http_input] [B] {binary} [127.0.0.1:41416, msgtype: service.logging.Batch, size: 207 bytes]
|
270
334
|
2020-06-09 19:04:13 +0500 [info]: #0 [protobuf_http_input] [B] Emitting message stream/batch [batch_size: 2 messages]...
|
@@ -273,14 +337,20 @@ $ curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@/<pat
|
|
273
337
|
2020-06-09 19:04:13 +0500 [info]: #0 [protobuf_http_input] [B] {json} [127.0.0.1:41416, msgtype: service.logging.Batch] Batch received! [batch_type: service.logging.Log, batch_size: 2 messages]
|
274
338
|
```
|
275
339
|
|
276
|
-
|
277
|
-
|
278
|
-
|
340
|
+
**`logbatch5.bin`**
|
341
|
+
|
342
|
+
`curl` command:
|
343
|
+
|
344
|
+
```bash
|
345
|
+
$ curl -X POST -H "Content-Type: application/octet-stream" \
|
346
|
+
--data-binary "@/<path>/logbatch5.bin" \
|
347
|
+
"http://localhost:8080/debug.test?msgtype=service.logging.Batch&batch=true"
|
279
348
|
{"status":"Batch received! [batch_type: service.logging.Log, batch_size: 5 messages]"}
|
280
349
|
```
|
281
350
|
|
282
|
-
`fluentd`
|
283
|
-
|
351
|
+
`fluentd` logs:
|
352
|
+
|
353
|
+
```text
|
284
354
|
2020-06-09 19:07:09 +0500 [info]: #0 [protobuf_http_input] [R] {binary} [127.0.0.1:41552, size: 486 bytes]
|
285
355
|
2020-06-09 19:07:09 +0500 [info]: #0 [protobuf_http_input] [B] {binary} [127.0.0.1:41552, msgtype: service.logging.Batch, size: 486 bytes]
|
286
356
|
2020-06-09 19:07:09 +0500 [info]: #0 [protobuf_http_input] [B] Emitting message stream/batch [batch_size: 5 messages]...
|
@@ -292,10 +362,19 @@ $ curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@/<pat
|
|
292
362
|
2020-06-09 19:07:09 +0500 [info]: #0 [protobuf_http_input] [B] {json} [127.0.0.1:41552, msgtype: service.logging.Batch] Batch received! [batch_type: service.logging.Log, batch_size: 5 messages]
|
293
363
|
```
|
294
364
|
|
295
|
-
For
|
365
|
+
For sample Batch message generation, see
|
366
|
+
[this](https://gist.github.com/iamAzeem/a8a24092132e1741a76956192f2104cc).
|
367
|
+
|
368
|
+
## Contribute
|
369
|
+
|
370
|
+
- Fork the project.
|
371
|
+
- Check out the latest `main` branch.
|
372
|
+
- Create a feature or bugfix branch from `main`.
|
373
|
+
- Commit and push your changes.
|
374
|
+
- Make sure to add and run tests locally: `bundle exec rake test`.
|
375
|
+
- Run `rubocop` locally and fix all the lint warnings.
|
376
|
+
- Submit the PR.
|
296
377
|
|
297
|
-
##
|
378
|
+
## License
|
298
379
|
|
299
|
-
|
300
|
-
* License
|
301
|
-
* Apache License, Version 2.0
|
380
|
+
[Apache 2.0](LICENSE)
|
data/Rakefile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('../lib', __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
|
4
6
|
Gem::Specification.new do |spec|
|
5
7
|
spec.name = 'fluent-plugin-protobuf-http'
|
6
|
-
spec.version = '0.
|
8
|
+
spec.version = '0.3.0'
|
7
9
|
spec.authors = ['Azeem Sajid']
|
8
10
|
spec.email = ['azeem.sajid@gmail.com']
|
9
11
|
|
@@ -20,8 +22,9 @@ Gem::Specification.new do |spec|
|
|
20
22
|
spec.test_files = test_files
|
21
23
|
spec.require_paths = ['lib']
|
22
24
|
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
25
|
+
spec.add_development_dependency 'bundler', '~> 2.1', '>= 2.1.0'
|
24
26
|
spec.add_development_dependency 'rake', '~> 12.0'
|
27
|
+
spec.add_development_dependency 'simplecov', '~> 0.12', '<= 0.12.2'
|
25
28
|
spec.add_development_dependency 'test-unit', '~> 3.0'
|
26
29
|
spec.add_runtime_dependency 'fluentd', ['>= 0.14.10', '< 2']
|
27
30
|
spec.add_runtime_dependency 'google-protobuf', '~> 3.12', '>= 3.12.2'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright 2020 Azeem Sajid
|
3
5
|
#
|
@@ -18,9 +20,11 @@ require 'fluent/config/error'
|
|
18
20
|
require 'fluent/plugin_helper/http_server'
|
19
21
|
require 'webrick/httputils'
|
20
22
|
require 'json'
|
23
|
+
require 'English'
|
21
24
|
|
22
25
|
module Fluent
|
23
26
|
module Plugin
|
27
|
+
# Implementation of HTTP input plugin for Protobuf
|
24
28
|
class ProtobufHttpInput < Fluent::Plugin::Input
|
25
29
|
Fluent::Plugin.register_input('protobuf_http', self)
|
26
30
|
|
@@ -46,10 +50,6 @@ module Fluent
|
|
46
50
|
config_argument :protocol, :enum, list: %i[tcp tls], default: :tcp
|
47
51
|
end
|
48
52
|
|
49
|
-
config_section :transform, required: false, multi: false, init: true, param_name: :transform_config do
|
50
|
-
config_argument :msgtype, :string
|
51
|
-
end
|
52
|
-
|
53
53
|
def initialize
|
54
54
|
super
|
55
55
|
|
@@ -61,16 +61,16 @@ module Fluent
|
|
61
61
|
def compile_protos
|
62
62
|
log.debug("Checking proto_dir [#{@proto_dir}]...")
|
63
63
|
|
64
|
-
path = File.expand_path(@proto_dir)
|
64
|
+
path = File.expand_path(@proto_dir)
|
65
65
|
raise Fluent::ConfigError, "protos_dir does not exist! [#{path}]" unless Dir.exist?(path)
|
66
66
|
|
67
|
-
@protos = Dir["#{path}/*.proto"]
|
67
|
+
@protos = Dir["#{path}/*.proto"]
|
68
68
|
raise Fluent::ConfigError, "Empty proto_dir! [#{path}]" unless @protos.any?
|
69
69
|
|
70
70
|
log.info("Compiling .proto files [#{@protos.length}]...")
|
71
71
|
|
72
72
|
`protoc --ruby_out=#{path} --proto_path=#{path} #{path}/*.proto`
|
73
|
-
raise Fluent::ConfigError, 'Could not compile! See error(s) above.' unless
|
73
|
+
raise Fluent::ConfigError, 'Could not compile! See error(s) above.' unless $CHILD_STATUS.success?
|
74
74
|
|
75
75
|
log.info("Compiled successfully:\n- #{@protos.join("\n- ")}")
|
76
76
|
|
@@ -82,8 +82,8 @@ module Fluent
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def get_compiled_proto(proto)
|
85
|
-
proto_suffix = '.proto'
|
86
|
-
compiled_proto_suffix = '_pb.rb'
|
85
|
+
proto_suffix = '.proto'
|
86
|
+
compiled_proto_suffix = '_pb.rb'
|
87
87
|
|
88
88
|
compiled_proto = proto.chomp(proto_suffix) + compiled_proto_suffix
|
89
89
|
raise Fluent::ConfigError, "Compiled proto not found! [#{compiled_proto}]" unless File.file?(compiled_proto)
|
@@ -117,7 +117,7 @@ module Fluent
|
|
117
117
|
msg_types = []
|
118
118
|
File.foreach(compiled_proto) do |line|
|
119
119
|
if line.lstrip.start_with?('add_message')
|
120
|
-
msg_type = line[/"([^"]*)"/, 1]
|
120
|
+
msg_type = line[/"([^"]*)"/, 1] # regex: <add_message> 'msg_type' <do>
|
121
121
|
msg_types.push(msg_type) unless msg_type.nil?
|
122
122
|
end
|
123
123
|
end
|
@@ -152,15 +152,13 @@ module Fluent
|
|
152
152
|
tls_opts = @transport_config.to_h
|
153
153
|
end
|
154
154
|
|
155
|
-
log.warn("#{@transform_config.to_h}")
|
156
|
-
|
157
155
|
log.info("Starting protobuf #{proto == :tcp ? 'HTTP' : 'HTTPS'} server [#{@bind}:#{@port}]...")
|
158
156
|
log.debug("TLS configuration:\n#{tls_opts}") if tls_opts
|
159
157
|
|
160
158
|
http_server_create_http_server(:protobuf_server, addr: @bind, port: @port, logger: log, proto: proto, tls_opts: tls_opts) do |server|
|
161
159
|
server.post("/#{tag}") do |req|
|
162
|
-
peeraddr = "#{req.peeraddr[2]}:#{req.peeraddr[1]}"
|
163
|
-
serialized_msg = req.body
|
160
|
+
peeraddr = "#{req.peeraddr[2]}:#{req.peeraddr[1]}" # ip:port
|
161
|
+
serialized_msg = req.body
|
164
162
|
|
165
163
|
log.info("[R] {#{@in_mode}} [#{peeraddr}, size: #{serialized_msg.length} bytes]")
|
166
164
|
log.debug("Dumping serialized message [#{serialized_msg.length} bytes]:\n#{serialized_msg}")
|
@@ -168,7 +166,7 @@ module Fluent
|
|
168
166
|
content_type = req.header['content-type'][0]
|
169
167
|
|
170
168
|
unless valid_content_type?(content_type)
|
171
|
-
status = "Invalid 'Content-Type' header! [#{content_type}]"
|
169
|
+
status = "Invalid 'Content-Type' header! [#{content_type}]"
|
172
170
|
log.warn("[X] Message rejected! [#{peeraddr}] #{status}")
|
173
171
|
next [400, { 'Content-Type' => 'application/json', 'Connection' => 'close' }, { 'status' => status }.to_json]
|
174
172
|
end
|
@@ -177,7 +175,7 @@ module Fluent
|
|
177
175
|
|
178
176
|
msgtype, batch = get_query_params(req.query_string)
|
179
177
|
unless @msgclass_lookup.key?(msgtype)
|
180
|
-
status = "Invalid 'msgtype' in 'query_string'! [#{msgtype}]"
|
178
|
+
status = "Invalid 'msgtype' in 'query_string'! [#{msgtype}]"
|
181
179
|
log.warn("[X] Message rejected! [#{peeraddr}] #{status}")
|
182
180
|
next [400, { 'Content-Type' => 'application/json', 'Connection' => 'close' }, { 'status' => status }.to_json]
|
183
181
|
end
|
@@ -187,7 +185,7 @@ module Fluent
|
|
187
185
|
deserialized_msg = deserialize_msg(msgtype, serialized_msg)
|
188
186
|
|
189
187
|
if deserialized_msg.nil?
|
190
|
-
status = "Incompatible message! [msgtype: #{msgtype}, size: #{serialized_msg.length} bytes]"
|
188
|
+
status = "Incompatible message! [msgtype: #{msgtype}, size: #{serialized_msg.length} bytes]"
|
191
189
|
log.warn("[X] Message rejected! [#{peeraddr}] #{status}")
|
192
190
|
next [400, { 'Content-Type' => 'application/json', 'Connection' => 'close' }, { 'status' => status }.to_json]
|
193
191
|
end
|
@@ -214,7 +212,7 @@ module Fluent
|
|
214
212
|
log.info("[B] {#{@in_mode}} [#{peeraddr}, msgtype: #{msgtype}, size: #{serialized_msg.length} bytes]")
|
215
213
|
|
216
214
|
if deserialized_msg.type.nil? || deserialized_msg.batch.nil? || deserialized_msg.batch.empty?
|
217
|
-
status = "Invalid 'batch' message! [msgtype: #{msgtype}, size: #{serialized_msg.length} bytes]"
|
215
|
+
status = "Invalid 'batch' message! [msgtype: #{msgtype}, size: #{serialized_msg.length} bytes]"
|
218
216
|
log.warn("[X] Message rejected! [#{peeraddr}] #{status}")
|
219
217
|
next [400, { 'Content-Type' => 'application/json', 'Connection' => 'close' }, { 'status' => status }.to_json]
|
220
218
|
end
|
@@ -234,7 +232,7 @@ module Fluent
|
|
234
232
|
|
235
233
|
router.emit_stream(@tag, stream)
|
236
234
|
|
237
|
-
status = "Batch received! [batch_type: #{batch_type}, batch_size: #{batch_size} messages]"
|
235
|
+
status = "Batch received! [batch_type: #{batch_type}, batch_size: #{batch_size} messages]"
|
238
236
|
log.info("[B] {#{@out_mode}} [#{peeraddr}, msgtype: #{msgtype}] #{status}")
|
239
237
|
[200, { 'Content-Type' => 'application/json', 'Connection' => 'close' }, { 'status' => status }.to_json]
|
240
238
|
end
|
@@ -242,8 +240,8 @@ module Fluent
|
|
242
240
|
end
|
243
241
|
|
244
242
|
def valid_content_type?(content_type)
|
245
|
-
hdr_binary = 'application/octet-stream'
|
246
|
-
hdr_json = 'application/json'
|
243
|
+
hdr_binary = 'application/octet-stream'
|
244
|
+
hdr_json = 'application/json'
|
247
245
|
|
248
246
|
case @in_mode
|
249
247
|
when :binary
|
@@ -284,7 +282,7 @@ module Fluent
|
|
284
282
|
rescue Google::Protobuf::ParseError => e
|
285
283
|
log.error("Incompatible message! [msgtype: #{msgtype}, size: #{serialized_msg.length} bytes] #{e}")
|
286
284
|
nil
|
287
|
-
rescue => e
|
285
|
+
rescue StandardError => e
|
288
286
|
log.error("Deserializaton failed! Error: #{e}")
|
289
287
|
nil
|
290
288
|
end
|
@@ -300,7 +298,7 @@ module Fluent
|
|
300
298
|
when :json
|
301
299
|
msgclass.encode_json(deserialized_msg)
|
302
300
|
end
|
303
|
-
rescue => e
|
301
|
+
rescue StandardError => e
|
304
302
|
log.error("Serialization failed! [msgtype: #{msgtype}, msg: #{deserialized_msg}] Error: #{e}")
|
305
303
|
nil
|
306
304
|
end
|
data/test/data/log.bin
ADDED
data/test/data/log.json
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"context":{"timestamp":"2020-06-01T16:24:19Z","hostOrIp":"192.168.xxx.xxx","serviceName":"test","user":"test"},"level":"INFO","message":"This is a test log generated by [./log.rb]."}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
service.logging.Log[
|
3
|
+
%
|
4
|
+
����192.168.xxx.xxxtest"test0This is a test log generated by [./logbatch.rb].[
|
5
|
+
%
|
6
|
+
����192.168.xxx.xxxtest"test0This is a test log generated by [./logbatch.rb].[
|
7
|
+
%
|
8
|
+
����192.168.xxx.xxxtest"test0This is a test log generated by [./logbatch.rb].[
|
9
|
+
%
|
10
|
+
����192.168.xxx.xxxtest"test0This is a test log generated by [./logbatch.rb].[
|
11
|
+
%
|
12
|
+
����192.168.xxx.xxxtest"test0This is a test log generated by [./logbatch.rb].
|
@@ -0,0 +1,31 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package service.logging;
|
4
|
+
|
5
|
+
import "google/protobuf/timestamp.proto";
|
6
|
+
|
7
|
+
message Log {
|
8
|
+
message Context {
|
9
|
+
google.protobuf.Timestamp timestamp = 1;
|
10
|
+
string host_or_ip = 2;
|
11
|
+
string service_name = 3;
|
12
|
+
string user = 4;
|
13
|
+
}
|
14
|
+
|
15
|
+
enum Level {
|
16
|
+
DEBUG = 0;
|
17
|
+
INFO = 1;
|
18
|
+
WARN = 2;
|
19
|
+
ERROR = 3;
|
20
|
+
FATAL = 4;
|
21
|
+
}
|
22
|
+
|
23
|
+
Context context = 1;
|
24
|
+
Level level = 2;
|
25
|
+
string message = 3;
|
26
|
+
}
|
27
|
+
|
28
|
+
message Batch {
|
29
|
+
string type = 1;
|
30
|
+
repeated Log batch = 2;
|
31
|
+
}
|
data/test/helper.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
|
5
|
-
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.expand_path('..', __dir__))
|
7
|
+
require 'test-unit'
|
8
|
+
require 'fluent/test'
|
9
|
+
require 'fluent/test/driver/input'
|
10
|
+
require 'fluent/test/helpers'
|
6
11
|
|
7
12
|
Test::Unit::TestCase.include(Fluent::Test::Helpers)
|
8
13
|
Test::Unit::TestCase.extend(Fluent::Test::Helpers)
|
@@ -1,18 +1,152 @@
|
|
1
|
-
|
2
|
-
require "fluent/plugin/in_protobuf_http.rb"
|
1
|
+
# frozen-string-literal: true
|
3
2
|
|
3
|
+
require 'helper'
|
4
|
+
require 'fluent/plugin/in_protobuf_http'
|
5
|
+
require 'net/http'
|
6
|
+
|
7
|
+
# Implementation of Test Class
|
4
8
|
class ProtobufHttpInputTest < Test::Unit::TestCase
|
5
9
|
setup do
|
6
10
|
Fluent::Test.setup
|
11
|
+
@log_bin = File.open('./test/data/log.bin', 'rb') { |f| f.read }
|
12
|
+
@log_json = File.open('./test/data/log.json', 'r') { |f| f.read }
|
13
|
+
@log_bin_batch = File.open('./test/data/logbatch5.bin', 'rb') { |f| f.read }
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_driver(conf)
|
17
|
+
Fluent::Test::Driver::Input.new(Fluent::Plugin::ProtobufHttpInput).configure(conf)
|
7
18
|
end
|
8
19
|
|
9
|
-
|
10
|
-
|
20
|
+
sub_test_case 'configure' do
|
21
|
+
test 'test default configuration' do
|
22
|
+
conf = %(
|
23
|
+
proto_dir ./test/data/protos
|
24
|
+
tag test
|
25
|
+
)
|
26
|
+
driver = create_driver(conf)
|
27
|
+
plugin = driver.instance
|
28
|
+
assert_equal plugin.class, Fluent::Plugin::ProtobufHttpInput
|
29
|
+
assert_equal plugin.bind, '0.0.0.0'
|
30
|
+
assert_equal plugin.port, 8080
|
31
|
+
assert_equal plugin.in_mode, :binary
|
32
|
+
assert_equal plugin.out_mode, :binary
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
sub_test_case 'route#emit' do
|
37
|
+
conf = %(
|
38
|
+
proto_dir ./test/data/protos
|
39
|
+
tag test
|
40
|
+
in_mode binary
|
41
|
+
out_mode json
|
42
|
+
)
|
43
|
+
|
44
|
+
test 'test invalid msgtype in query string i.e. empty or mismatch' do
|
45
|
+
driver = create_driver(conf)
|
46
|
+
res_codes = []
|
47
|
+
driver.run do
|
48
|
+
path = '/test'
|
49
|
+
res = post(path, @log_bin)
|
50
|
+
res_codes << res.code
|
51
|
+
end
|
52
|
+
assert_equal 1, res_codes.size
|
53
|
+
assert_equal '400', res_codes[0]
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'test incoming type mismatch [in_mode != Content-Type]' do
|
57
|
+
conf = %(
|
58
|
+
proto_dir ./test/data/protos
|
59
|
+
tag test
|
60
|
+
in_mode binary
|
61
|
+
out_mode json
|
62
|
+
)
|
63
|
+
driver = create_driver(conf)
|
64
|
+
res_codes = []
|
65
|
+
driver.run do
|
66
|
+
path = '/test?msgtype=service.logging.Log'
|
67
|
+
res = post(path, @log_bin, :json)
|
68
|
+
res_codes << res.code
|
69
|
+
end
|
70
|
+
assert_equal 1, res_codes.size
|
71
|
+
assert_equal '400', res_codes[0]
|
72
|
+
end
|
73
|
+
|
74
|
+
test 'test single message (Binary to JSON)' do
|
75
|
+
driver = create_driver(conf)
|
76
|
+
res_codes = []
|
77
|
+
driver.run do
|
78
|
+
path = '/test?msgtype=service.logging.Log'
|
79
|
+
res = post(path, @log_bin)
|
80
|
+
res_codes << res.code
|
81
|
+
end
|
82
|
+
assert_equal 1, res_codes.size
|
83
|
+
assert_equal '200', res_codes[0]
|
84
|
+
end
|
85
|
+
|
86
|
+
test 'test single message (JSON to Binary)' do
|
87
|
+
conf = %(
|
88
|
+
proto_dir ./test/data/protos
|
89
|
+
tag test
|
90
|
+
in_mode json
|
91
|
+
out_mode binary
|
92
|
+
)
|
93
|
+
driver = create_driver(conf)
|
94
|
+
res_codes = []
|
95
|
+
driver.run do
|
96
|
+
path = '/test?msgtype=service.logging.Log'
|
97
|
+
res = post(path, @log_json, :json)
|
98
|
+
res_codes << res.code
|
99
|
+
end
|
100
|
+
assert_equal 1, res_codes.size
|
101
|
+
assert_equal '200', res_codes[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
test 'test batch messages (Binary to JSON)' do
|
105
|
+
conf = %(
|
106
|
+
proto_dir ./test/data/protos
|
107
|
+
tag test
|
108
|
+
in_mode binary
|
109
|
+
out_mode json
|
110
|
+
)
|
111
|
+
driver = create_driver(conf)
|
112
|
+
res_codes = []
|
113
|
+
driver.run do
|
114
|
+
path = '/test?msgtype=service.logging.Batch&batch=true'
|
115
|
+
res = post(path, @log_bin_batch)
|
116
|
+
res_codes << res.code
|
117
|
+
end
|
118
|
+
assert_equal 1, res_codes.size
|
119
|
+
assert_equal '200', res_codes[0]
|
120
|
+
end
|
121
|
+
|
122
|
+
test 'test incompatible message' do
|
123
|
+
conf = %(
|
124
|
+
proto_dir ./test/data/protos
|
125
|
+
tag test
|
126
|
+
in_mode binary
|
127
|
+
out_mode json
|
128
|
+
)
|
129
|
+
driver = create_driver(conf)
|
130
|
+
res_codes = []
|
131
|
+
driver.run do
|
132
|
+
path = '/test?msgtype=service.logging.Log'
|
133
|
+
res = post(path, @log_bin_batch)
|
134
|
+
res_codes << res.code
|
135
|
+
end
|
136
|
+
assert_equal 1, res_codes.size
|
137
|
+
assert_equal '400', res_codes[0]
|
138
|
+
end
|
11
139
|
end
|
12
140
|
|
13
141
|
private
|
14
142
|
|
15
|
-
def
|
16
|
-
|
143
|
+
def post(path, body, type = :binary)
|
144
|
+
http = Net::HTTP.new('127.0.0.1', 8080)
|
145
|
+
content_type = 'application/octet-stream'
|
146
|
+
content_type = 'application/json' if type == :json
|
147
|
+
header = { 'Content-Type' => content_type }
|
148
|
+
req = Net::HTTP::Post.new(path, header)
|
149
|
+
req.body = body
|
150
|
+
http.request(req)
|
17
151
|
end
|
18
152
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-protobuf-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Azeem Sajid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
19
|
+
version: '2.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.1.0
|
20
23
|
type: :development
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1
|
29
|
+
version: '2.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.1.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rake
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +44,26 @@ dependencies:
|
|
38
44
|
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: '12.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: simplecov
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.12'
|
54
|
+
- - "<="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.12.2
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0.12'
|
64
|
+
- - "<="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.12.2
|
41
67
|
- !ruby/object:Gem::Dependency
|
42
68
|
name: test-unit
|
43
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,13 +126,19 @@ executables: []
|
|
100
126
|
extensions: []
|
101
127
|
extra_rdoc_files: []
|
102
128
|
files:
|
129
|
+
- ".github/workflows/ci.yml"
|
103
130
|
- ".gitignore"
|
131
|
+
- ".rubocop.yml"
|
104
132
|
- Gemfile
|
105
133
|
- LICENSE
|
106
134
|
- README.md
|
107
135
|
- Rakefile
|
108
136
|
- fluent-plugin-protobuf-http.gemspec
|
109
137
|
- lib/fluent/plugin/in_protobuf_http.rb
|
138
|
+
- test/data/log.bin
|
139
|
+
- test/data/log.json
|
140
|
+
- test/data/logbatch5.bin
|
141
|
+
- test/data/protos/log.proto
|
110
142
|
- test/helper.rb
|
111
143
|
- test/plugin/test_in_protobuf_http.rb
|
112
144
|
homepage: https://github.com/iamAzeem/fluent-plugin-protobuf-http
|
@@ -134,5 +166,9 @@ signing_key:
|
|
134
166
|
specification_version: 4
|
135
167
|
summary: fluentd HTTP Input Plugin for Protocol Buffers
|
136
168
|
test_files:
|
169
|
+
- test/data/log.bin
|
170
|
+
- test/data/log.json
|
171
|
+
- test/data/logbatch5.bin
|
172
|
+
- test/data/protos/log.proto
|
137
173
|
- test/helper.rb
|
138
174
|
- test/plugin/test_in_protobuf_http.rb
|