fluent-plugin-json-transform_ex 0.1.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/.gitignore +5 -0
- data/README.md +103 -0
- data/fluent-plugin-json-transform_ex.gemspec +20 -0
- data/lib/fluent/plugin/filter_json_transform_ex.rb +36 -0
- data/lib/fluent/plugin/parser_json_transform_ex.rb +44 -0
- data/lib/transform/flatten.rb +26 -0
- data/lib/transform/nothing.rb +5 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 700d72367418f0f7cf2630152aff119cb796e17fcf6aedd25462b73d76893853
|
4
|
+
data.tar.gz: 4f95f6f62c7a7de3d7004f3b1c2a86c556edf2bf2210c5a9c9e67fd7986eceb6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 943274519c5c26f54c57419e2be56b61d9483eae83c821e66dea683a32f9edda3d40b61cdbc068442ec1a5349e17855ea04b62322ad528f6de83970857769903
|
7
|
+
data.tar.gz: 5fcc73c15e2cd92a964639e876d91c9e9e479e74b657d527b5f424695cf8fda40f05a0a9c2ae856cbd062d6cad9eafe28ec2ac2bd2fe8a95992cebf48702089e
|
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# JSON Transform parser plugin for Fluentd
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
This is a [parser plugin](http://docs.fluentd.org/articles/parser-plugin-overview) for fluentd. It is **INCOMPATIBLE WITH FLUENTD v0.10.45 AND BELOW.**
|
5
|
+
|
6
|
+
|
7
|
+
It was created for the purpose of modifying [**good.js**](https://github.com/hapijs/good) logs
|
8
|
+
before storing them in Elasticsearch. It may not be useful for any other purpose, but be creative.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
```bash
|
12
|
+
gem install fluent-plugin-json-transform_ex --version 0.0.1
|
13
|
+
```
|
14
|
+
|
15
|
+
## Configuration
|
16
|
+
```
|
17
|
+
<source>
|
18
|
+
type [tail|tcp|udp|syslog|http] # or a custom input type which accepts the "format" parameter
|
19
|
+
format json_transform
|
20
|
+
transform_script [nothing|flatten|custom]
|
21
|
+
script_path "/home/grayson/transform_script.rb" # ignored if transform_script != custom
|
22
|
+
class_name "CustomJSONTransformer" # [optional] default value is "JSONTransformer", ignored if transform_script != custom
|
23
|
+
</source>
|
24
|
+
```
|
25
|
+
|
26
|
+
`transform_script`: `nothing` to do nothing, `flatten` to flatten JSON by concatenating nested keys (see below), or `custom`
|
27
|
+
|
28
|
+
`script_path`: ignored if not using `custom` script. Point this to a Ruby script which implements the class from `class_name` parameter.
|
29
|
+
|
30
|
+
`class_name`: [optional] ignored if not using `custom` script. Define name of a class which is used for transformation in `script_path` script.
|
31
|
+
|
32
|
+
### Flatten script
|
33
|
+
Flattens nested JSON by concatenating nested keys with '.'. Example:
|
34
|
+
|
35
|
+
```
|
36
|
+
{
|
37
|
+
"hello": {
|
38
|
+
"world": true
|
39
|
+
},
|
40
|
+
"goodbye": {
|
41
|
+
"for": {
|
42
|
+
"now": true,
|
43
|
+
"ever": false
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
```
|
48
|
+
|
49
|
+
Becomes
|
50
|
+
|
51
|
+
```
|
52
|
+
{
|
53
|
+
"hello.world": true,
|
54
|
+
"goodbye.for.now": true,
|
55
|
+
"goodbye.for.ever": false
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
### Filter Option
|
60
|
+
If you want to flatten your json after doing other parsing from the original source log.
|
61
|
+
```
|
62
|
+
<filter pattern>
|
63
|
+
@type json_transform
|
64
|
+
transform_script [nothing|flatten|custom]
|
65
|
+
script_path "/home/grayson/transform_script.rb" # ignored if transform_script != custom
|
66
|
+
class_name "CustomJSONTransformer" # [optional] default value is "JSONTransformer", ignored if transform_script != custom
|
67
|
+
</filter>
|
68
|
+
```
|
69
|
+
|
70
|
+
|
71
|
+
## Implementing transformer class
|
72
|
+
|
73
|
+
The transformer class should have an instance method `transform` which takes a Ruby hash and returns a Ruby hash. Pay attention that the name of a class should be the same as you defined in `class_name` parameter or `JSONTransformer` in case `class_name` parameter is not defined:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# lib/transform/flatten.rb
|
77
|
+
class JSONTransformer # or any class name defined in class_name parameter
|
78
|
+
def transform(json)
|
79
|
+
return flatten(json, "")
|
80
|
+
end
|
81
|
+
|
82
|
+
def flatten(json, prefix)
|
83
|
+
json.keys.each do |key|
|
84
|
+
if prefix.empty?
|
85
|
+
full_path = key
|
86
|
+
else
|
87
|
+
full_path = [prefix, key].join('.')
|
88
|
+
end
|
89
|
+
|
90
|
+
if json[key].is_a?(Hash)
|
91
|
+
value = json[key]
|
92
|
+
json.delete key
|
93
|
+
json.merge! flatten(value, full_path)
|
94
|
+
else
|
95
|
+
value = json[key]
|
96
|
+
json.delete key
|
97
|
+
json[full_path] = value
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return json
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "fluent-plugin-json-transform_ex"
|
4
|
+
spec.version = "0.1.0"
|
5
|
+
spec.authors = ["Grayson Chao", "Yevhen Fabizhevskyi"]
|
6
|
+
spec.email = ["grayson.chao@gmail.com", "fabasoad@gmail.com"]
|
7
|
+
spec.description = %q{Input parser plugin which allows arbitrary transformation of input JSON}
|
8
|
+
spec.summary = %q{Input parser plugin which allows arbitrary transformation of input JSON}
|
9
|
+
spec.homepage = "https://github.com/fabasoad/fluent-plugin-json-transform_ex"
|
10
|
+
spec.license = "MIT"
|
11
|
+
|
12
|
+
spec.files = `git ls-files`.split($/)
|
13
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
14
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
|
+
spec.require_paths = ["lib"]
|
16
|
+
|
17
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
18
|
+
spec.add_development_dependency "rake"
|
19
|
+
spec.add_development_dependency "rspec"
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Fluent
|
2
|
+
class JSONTransformFilter < Filter
|
3
|
+
Fluent::Plugin.register_filter('json_transform_ex', self)
|
4
|
+
|
5
|
+
DEFAULTS = [ 'nothing', 'flatten' ]
|
6
|
+
DEFAULT_CLASS_NAME = 'JSONTransformer'
|
7
|
+
|
8
|
+
include Configurable
|
9
|
+
config_param :transform_script, :string
|
10
|
+
config_param :script_path, :string
|
11
|
+
config_param :class_name, :string
|
12
|
+
|
13
|
+
def configure(conf)
|
14
|
+
@transform_script = conf['transform_script']
|
15
|
+
|
16
|
+
if DEFAULTS.include?(@transform_script)
|
17
|
+
@transform_script = "#{__dir__}/../../transform/#{@transform_script}.rb"
|
18
|
+
className = DEFAULT_CLASS_NAME
|
19
|
+
elsif @transform_script == 'custom'
|
20
|
+
@transform_script = conf['script_path']
|
21
|
+
className = conf['class_name'] || DEFAULT_CLASS_NAME
|
22
|
+
end
|
23
|
+
|
24
|
+
require @transform_script
|
25
|
+
begin
|
26
|
+
@transformer = Object.const_get(className).new
|
27
|
+
rescue NameError
|
28
|
+
@transformer = Object.const_get(DEFAULT_CLASS_NAME).new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def filter(tag, time, record)
|
33
|
+
return @transformer.transform(record)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Fluent
|
2
|
+
class TextParser
|
3
|
+
class JSONTransformParser
|
4
|
+
DEFAULTS = [ 'nothing', 'flatten' ]
|
5
|
+
DEFAULT_CLASS_NAME = 'JSONTransformer'
|
6
|
+
|
7
|
+
include Configurable
|
8
|
+
config_param :transform_script, :string
|
9
|
+
config_param :script_path, :string
|
10
|
+
config_param :class_name, :string
|
11
|
+
|
12
|
+
def configure(conf)
|
13
|
+
@transform_script = conf['transform_script']
|
14
|
+
|
15
|
+
if DEFAULTS.include?(@transform_script)
|
16
|
+
@transform_script = "#{__dir__}/../../transform/#{@transform_script}.rb"
|
17
|
+
className = DEFAULT_CLASS_NAME
|
18
|
+
elsif @transform_script == 'custom'
|
19
|
+
@transform_script = conf['script_path']
|
20
|
+
className = conf['class_name'] || DEFAULT_CLASS_NAME
|
21
|
+
end
|
22
|
+
|
23
|
+
require @transform_script
|
24
|
+
begin
|
25
|
+
@transformer = Object.const_get(className).new
|
26
|
+
rescue NameError
|
27
|
+
@transformer = Object.const_get(DEFAULT_CLASS_NAME).new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def call(text)
|
32
|
+
raw_json = JSON.parse(text)
|
33
|
+
return nil, @transformer.transform(raw_json)
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse(text)
|
37
|
+
raw_json = JSON.parse(text)
|
38
|
+
return nil, @transformer.transform(raw_json)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
register_template("json_transform_ex", Proc.new { JSONTransformParser.new })
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class JSONTransformer
|
2
|
+
def transform(json)
|
3
|
+
return flatten(json, "")
|
4
|
+
end
|
5
|
+
|
6
|
+
def flatten(json, prefix)
|
7
|
+
json.keys.each do |key|
|
8
|
+
if prefix.empty?
|
9
|
+
full_path = key
|
10
|
+
else
|
11
|
+
full_path = [prefix, key].join('.')
|
12
|
+
end
|
13
|
+
|
14
|
+
if json[key].is_a?(Hash)
|
15
|
+
value = json[key]
|
16
|
+
json.delete key
|
17
|
+
json.merge! flatten(value, full_path)
|
18
|
+
else
|
19
|
+
value = json[key]
|
20
|
+
json.delete key
|
21
|
+
json[full_path] = value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
return json
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-json-transform_ex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Grayson Chao
|
8
|
+
- Yevhen Fabizhevskyi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-07-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.3'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
description: Input parser plugin which allows arbitrary transformation of input JSON
|
57
|
+
email:
|
58
|
+
- grayson.chao@gmail.com
|
59
|
+
- fabasoad@gmail.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- README.md
|
66
|
+
- fluent-plugin-json-transform_ex.gemspec
|
67
|
+
- lib/fluent/plugin/filter_json_transform_ex.rb
|
68
|
+
- lib/fluent/plugin/parser_json_transform_ex.rb
|
69
|
+
- lib/transform/flatten.rb
|
70
|
+
- lib/transform/nothing.rb
|
71
|
+
homepage: https://github.com/fabasoad/fluent-plugin-json-transform_ex
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.7.7
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Input parser plugin which allows arbitrary transformation of input JSON
|
95
|
+
test_files: []
|