logstash-filter-amelia 1.0.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/README.md +70 -0
- data/lib/logstash/filters/amelia.rb +128 -0
- data/logstash-filter-amelia.gemspec +23 -0
- data/spec/filters/amelia_spec.rb +80 -0
- data/spec/spec_helper.rb +2 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 76bbf584bfef4c42804a90c83de7a9b0600923d3
|
4
|
+
data.tar.gz: fc78f7ca2dcd2937070421329b2aad7f681cc585
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b47323b5aa9b0730d5d28eef08703e53afbc9acaa293cd25485c48c83620d7b870a55390daa85833bd8c3f4cf850246d3e463ce76daef400f90f4377df0d7ee
|
7
|
+
data.tar.gz: 1eb8adeb7c10e618a2e37d470d031037edadc0de57f949500961c734c711e234f1aca0c6a6aefef2ad7eea056609c59b0112e3a57c2c1e517c6ba90d95027048
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
## 2.0.0
|
2
|
+
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
3
|
+
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
4
|
+
- Dependency on logstash-core update to 2.0
|
5
|
+
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Logstash Plugin
|
2
|
+
|
3
|
+
|
4
|
+
## Developing
|
5
|
+
|
6
|
+
### 1. Plugin Developement and Testing
|
7
|
+
|
8
|
+
#### Code
|
9
|
+
- To get started, you'll need JRuby with the Bundler gem installed.
|
10
|
+
|
11
|
+
- Install dependencies
|
12
|
+
```sh
|
13
|
+
bundle install
|
14
|
+
```
|
15
|
+
|
16
|
+
#### Test
|
17
|
+
|
18
|
+
- Update your dependencies
|
19
|
+
|
20
|
+
```sh
|
21
|
+
bundle install
|
22
|
+
```
|
23
|
+
|
24
|
+
- Run tests
|
25
|
+
|
26
|
+
```sh
|
27
|
+
bundle exec rspec
|
28
|
+
```
|
29
|
+
|
30
|
+
### 2. Running your unpublished Plugin in Logstash
|
31
|
+
|
32
|
+
#### 2.1 Run in a local Logstash clone
|
33
|
+
|
34
|
+
- Edit Logstash `Gemfile` and add the local plugin path, for example:
|
35
|
+
```ruby
|
36
|
+
gem "logstash-filter-awesome", :path => "/your/local/logstash-filter-awesome"
|
37
|
+
```
|
38
|
+
- Install plugin
|
39
|
+
```sh
|
40
|
+
bin/plugin install --no-verify
|
41
|
+
```
|
42
|
+
- Run Logstash with your plugin
|
43
|
+
```sh
|
44
|
+
bin/logstash -e 'filter {awesome {}}'
|
45
|
+
```
|
46
|
+
At this point any modifications to the plugin code will be applied to this local Logstash setup. After modifying the plugin, simply rerun Logstash.
|
47
|
+
|
48
|
+
#### 2.2 Run in an installed Logstash
|
49
|
+
|
50
|
+
You can use the same **2.1** method to run your plugin in an installed Logstash by editing its `Gemfile` and pointing the `:path` to your local plugin development directory or you can build the gem and install it using:
|
51
|
+
|
52
|
+
- Build your plugin gem
|
53
|
+
```sh
|
54
|
+
gem build logstash-filter-awesome.gemspec
|
55
|
+
```
|
56
|
+
- Install the plugin from the Logstash home
|
57
|
+
```sh
|
58
|
+
bin/plugin install /your/local/plugin/logstash-filter-awesome.gem
|
59
|
+
```
|
60
|
+
- Start Logstash and proceed to test the plugin
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
|
65
|
+
|
66
|
+
Programming is not a required skill. Whatever you've seen about open source and maintainers or community members saying "send patches or die" - you will not see that here.
|
67
|
+
|
68
|
+
It is more important to the community that you are able to contribute.
|
69
|
+
|
70
|
+
For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/filters/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
|
5
|
+
# This example filter will replace the contents of the default
|
6
|
+
# message field with whatever you specify in the configuration.
|
7
|
+
#
|
8
|
+
# It is only intended to be used as an example.
|
9
|
+
class LogStash::Filters::Amelia < LogStash::Filters::Base
|
10
|
+
|
11
|
+
# Setting the config_name here is required. This is how you
|
12
|
+
# configure this filter from your Logstash config.
|
13
|
+
#
|
14
|
+
# filter {
|
15
|
+
# amelia {
|
16
|
+
# data => "fieldname"
|
17
|
+
# }
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
config_name "amelia"
|
21
|
+
|
22
|
+
# field name with the data to parse
|
23
|
+
config :data, :validate => :string, :required => true
|
24
|
+
|
25
|
+
# scope under which to expand data
|
26
|
+
config :scope_name, :validate => :string, :required => true
|
27
|
+
|
28
|
+
# direction : in / out
|
29
|
+
config :direction, :validate => :string, :required => true
|
30
|
+
|
31
|
+
|
32
|
+
public
|
33
|
+
def register
|
34
|
+
# @scope_name and @data will be created automaticaly populated with config options
|
35
|
+
end
|
36
|
+
|
37
|
+
public
|
38
|
+
def filter(event)
|
39
|
+
|
40
|
+
if @direction=="in"
|
41
|
+
event[@scope_name] = {}
|
42
|
+
event[@scope_name]['direction'] = 'in'
|
43
|
+
|
44
|
+
# parsing for folloging block
|
45
|
+
|
46
|
+
# 0008 ehelmeri -> user
|
47
|
+
# 0024 9FFgaORTvtv/u3Pe3AXFFw== -> pwd
|
48
|
+
# 0005 3.354 -> version
|
49
|
+
# 0019 ListJobsByCodeAppli -> function
|
50
|
+
# 02 de -> lng
|
51
|
+
|
52
|
+
position = 0
|
53
|
+
[['user', 4], ['pwd', 4], ['version', 4], ['function', 4], ['lng', 2]].each do |field|
|
54
|
+
length = event[@data][position, field[1]].to_i
|
55
|
+
position += field[1]
|
56
|
+
event[@scope_name][field[0]]= event[@data][position, length]
|
57
|
+
position += length
|
58
|
+
end
|
59
|
+
|
60
|
+
# parsing for rest of the block
|
61
|
+
# 0001 0002 1 elt de 2 clefs
|
62
|
+
# 0004 0007 PROG LISI012
|
63
|
+
# 0004 0016 FUNC ListeTracabilite
|
64
|
+
# parsing headers
|
65
|
+
|
66
|
+
event[@scope_name]['parameters']= parse_field event[@data], position
|
67
|
+
end
|
68
|
+
|
69
|
+
if @direction=="out"
|
70
|
+
event[@scope_name] = {}
|
71
|
+
event[@scope_name]['direction'] = 'out'
|
72
|
+
|
73
|
+
# parsing for folloging block
|
74
|
+
|
75
|
+
# 0001 -> 1 paquet
|
76
|
+
# 0001 0 -> CR sur 1 char
|
77
|
+
# 0000 -> libelle
|
78
|
+
|
79
|
+
event[@scope_name]['paquet']= event[@data][0, 4].to_i
|
80
|
+
position = 4
|
81
|
+
[ ['return_code', 4], ['libelle', 4]].each do |field|
|
82
|
+
length = event[@data][position, field[1]].to_i
|
83
|
+
position += field[1]
|
84
|
+
event[@scope_name][field[0]]= event[@data][position, length]
|
85
|
+
position += length
|
86
|
+
end
|
87
|
+
|
88
|
+
# parsing for rest of the block
|
89
|
+
# 0001 0017 1 elt à 17 clef/val
|
90
|
+
# 0005 0009 timeC 145252452
|
91
|
+
# 00090001timeExcel000050008dateM2016021600100001nbFichiers000060002status1000110001nbFicAbnErr000050008dateC2016021600050007seqID105052700120001nbAbonnement000070001timePdf000130000nomAbonnement00040007progLISI09100080001nbEpingl000050009timeM14525276300150001seqIdAbonnement000040007userSMILLOT00070001timeTxt0
|
92
|
+
event[@scope_name]['parameters']= parse_field event[@data], position
|
93
|
+
end
|
94
|
+
|
95
|
+
# filter_matched should go in the last line of our successful code
|
96
|
+
filter_matched(event)
|
97
|
+
end # def filter
|
98
|
+
|
99
|
+
|
100
|
+
private
|
101
|
+
# parses list of hashes from the block, starting a indicated position
|
102
|
+
def parse_field data, position
|
103
|
+
retour = []
|
104
|
+
list_length = data[position, 4].to_i
|
105
|
+
position += 4
|
106
|
+
args_length = data[position, 4].to_i
|
107
|
+
position += 4
|
108
|
+
|
109
|
+
list_length.times do |i|
|
110
|
+
current_args = {}
|
111
|
+
args_length.times do
|
112
|
+
key_length = data[position, 4].to_i
|
113
|
+
position += 4
|
114
|
+
value_length = data[position, 4].to_i
|
115
|
+
position += 4
|
116
|
+
|
117
|
+
key = data[position, key_length]
|
118
|
+
position += key_length
|
119
|
+
|
120
|
+
value = data[position, value_length]
|
121
|
+
position += value_length
|
122
|
+
current_args[key] = value
|
123
|
+
end
|
124
|
+
retour << current_args
|
125
|
+
end
|
126
|
+
retour
|
127
|
+
end
|
128
|
+
end # class LogStash::Filters::Example
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'logstash-filter-amelia'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.licenses = ['Apache License (2.0)']
|
5
|
+
s.summary = "This filter extracts data based on the homegrown AMELIA serialisation"
|
6
|
+
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program. The aim is to parse non standard serialization format, see spec for format descitpion"
|
7
|
+
s.authors = ["LISI Automotive"]
|
8
|
+
s.email = 'contact@lisi-automotive.com'
|
9
|
+
s.homepage = "http://www.lisi-automotive.com"
|
10
|
+
s.require_paths = ["lib"]
|
11
|
+
|
12
|
+
# Files
|
13
|
+
s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
|
14
|
+
# Tests
|
15
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
16
|
+
|
17
|
+
# Special flag to let us know this is actually a logstash plugin
|
18
|
+
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
|
19
|
+
|
20
|
+
# Gem dependencies
|
21
|
+
s.add_runtime_dependency "logstash-core", ">= 1.5.4", "< 3.0.0"
|
22
|
+
s.add_development_dependency 'logstash-devutils'
|
23
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require "logstash/filters/amelia"
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
describe LogStash::Filters::Amelia do
|
8
|
+
describe "parse input" do
|
9
|
+
# breakdown for line 0008ehelmeri00249FFgaORTvtv/u3Pe3AXFFw==00053.3540019ListJobsByCodeAppli02de0001000200040007PROGLISI01200040016FUNCListeTracabilite
|
10
|
+
# 0008 ehelmeri -> user
|
11
|
+
# 0024 9FFgaORTvtv/u3Pe3AXFFw== -> pwd
|
12
|
+
# 0005 3.354 -> version
|
13
|
+
# 0019 ListJobsByCodeAppli -> function
|
14
|
+
# 02 de -> lng
|
15
|
+
# 0001 0002 1 elt de 2 clefs
|
16
|
+
# 0004 0007 PROG LISI012
|
17
|
+
# 0004 0016 FUNC ListeTracabilite
|
18
|
+
let(:config) do <<-CONFIG
|
19
|
+
filter {
|
20
|
+
amelia {
|
21
|
+
direction => "in"
|
22
|
+
data => "payload"
|
23
|
+
scope_name => "result"
|
24
|
+
}
|
25
|
+
}
|
26
|
+
CONFIG
|
27
|
+
end
|
28
|
+
|
29
|
+
sample("payload" => "0008ehelmeri00249FFgaORTvtv/u3Pe3AXFFw==00053.3540019ListJobsByCodeAppli02de0001000200040007PROGLISI01200040016FUNCListeTracabilite") do
|
30
|
+
expect(subject).to include("result")
|
31
|
+
expect(subject['result']['direction']).to eql 'in'
|
32
|
+
expect(subject['result']['user']).to eql 'ehelmeri'
|
33
|
+
expect(subject['result']['function']).to eql 'ListJobsByCodeAppli'
|
34
|
+
expect(subject['result']['lng']).to eql 'de'
|
35
|
+
end
|
36
|
+
|
37
|
+
sample("payload" => "0008ehelmeri00249FFgaORTvtv/u3Pe3AXFFw==00053.3540019ListJobsByCodeAppli02de0001000200040007PROGLISI01200040016FUNCListeTracabilite") do
|
38
|
+
expect(subject).to include("result")
|
39
|
+
expect(subject['result']['parameters']).to be_a Array
|
40
|
+
expect(subject['result']['parameters'][0]['PROG']).to eql 'LISI012'
|
41
|
+
expect(subject['result']['parameters'][0]['FUNC']).to eql 'ListeTracabilite'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "parse output" do
|
46
|
+
# breakdown for 00010001000000001001700050009timeC14525245200090001timeExcel000050008dateM2016021600100001nbFichiers000060002status1000110001nbFicAbnErr000050008dateC2016021600050007seqID105052700120001nbAbonnement000070001timePdf000130000nomAbonnement00040007progLISI09100080001nbEpingl000050009timeM14525276300150001seqIdAbonnement000040007userSMILLOT00070001timeTxt0
|
47
|
+
# 0001 -> 1 paquet
|
48
|
+
# 0001 0 -> CR sur 1 char
|
49
|
+
# 0000 -> libelle
|
50
|
+
# 0001 0017 1 elt à 17 clef/val
|
51
|
+
# 0005 0009 timeC 145252452
|
52
|
+
# 00090001timeExcel000050008dateM2016021600100001nbFichiers000060002status1000110001nbFicAbnErr000050008dateC2016021600050007seqID105052700120001nbAbonnement000070001timePdf000130000nomAbonnement00040007progLISI09100080001nbEpingl000050009timeM14525276300150001seqIdAbonnement000040007userSMILLOT00070001timeTxt0
|
53
|
+
let(:config) do <<-CONFIG
|
54
|
+
filter {
|
55
|
+
amelia {
|
56
|
+
direction => "out"
|
57
|
+
data => "payload"
|
58
|
+
scope_name => "result"
|
59
|
+
}
|
60
|
+
}
|
61
|
+
CONFIG
|
62
|
+
end
|
63
|
+
|
64
|
+
sample("payload" => "00010001000000001001700050009timeC14525245200090001timeExcel000050008dateM2016021600100001nbFichiers000060002status1000110001nbFicAbnErr000050008dateC2016021600050007seqID105052700120001nbAbonnement000070001timePdf000130000nomAbonnement00040007progLISI09100080001nbEpingl000050009timeM14525276300150001seqIdAbonnement000040007userSMILLOT00070001timeTxt0") do
|
65
|
+
expect(subject).to include("result")
|
66
|
+
expect(subject['result']['paquet']).to eql 1
|
67
|
+
expect(subject['result']['direction']).to eql 'out'
|
68
|
+
expect(subject['result']['return_code']).to eql '0'
|
69
|
+
expect(subject['result']['libelle']).to eql ''
|
70
|
+
end
|
71
|
+
|
72
|
+
sample("payload" => "00010001000000001001700050009timeC14525245200090001timeExcel000050008dateM2016021600100001nbFichiers000060002status1000110001nbFicAbnErr000050008dateC2016021600050007seqID105052700120001nbAbonnement000070001timePdf000130000nomAbonnement00040007progLISI09100080001nbEpingl000050009timeM14525276300150001seqIdAbonnement000040007userSMILLOT00070001timeTxt0") do
|
73
|
+
expect(subject).to include("result")
|
74
|
+
expect(subject['result']['parameters']).to be_a Array
|
75
|
+
expect(subject['result']['parameters'][0]['timeC']).to eql '145252452'
|
76
|
+
expect(subject['result']['parameters'][0]['timeTxt']).to eql '0'
|
77
|
+
expect(subject['result']['parameters'][0].keys.length).to eql 17
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-filter-amelia
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- LISI Automotive
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: logstash-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.4
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.4
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: logstash-devutils
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: This gem is a logstash plugin required to be installed on top of the
|
48
|
+
Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not
|
49
|
+
a stand-alone program. The aim is to parse non standard serialization format, see
|
50
|
+
spec for format descitpion
|
51
|
+
email: contact@lisi-automotive.com
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- CHANGELOG.md
|
57
|
+
- Gemfile
|
58
|
+
- README.md
|
59
|
+
- lib/logstash/filters/amelia.rb
|
60
|
+
- logstash-filter-amelia.gemspec
|
61
|
+
- spec/filters/amelia_spec.rb
|
62
|
+
- spec/spec_helper.rb
|
63
|
+
homepage: http://www.lisi-automotive.com
|
64
|
+
licenses:
|
65
|
+
- Apache License (2.0)
|
66
|
+
metadata:
|
67
|
+
logstash_plugin: 'true'
|
68
|
+
logstash_group: filter
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.2.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: This filter extracts data based on the homegrown AMELIA serialisation
|
89
|
+
test_files:
|
90
|
+
- spec/filters/amelia_spec.rb
|
91
|
+
- spec/spec_helper.rb
|