Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prometheus format filter plugin #15

Merged
merged 8 commits into from
Apr 25, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ RUN apk add --no-cache --update --virtual .build-deps sudo build-base ruby-dev \
&& gem install snappy

RUN gem install fluent-plugin-sumologic_output \
&& gem install fluent-plugin-rewrite-tag-filter \
&& gem install fluent-plugin-carbon-v2 \
&& gem install fluent-plugin-prometheus-format \
&& gem install fluent-plugin-datapoint \
&& gem install fluent-plugin-rewrite-tag-filter \
&& gem install fluent-plugin-protobuf

RUN gem sources --clear-all \
Expand Down
2 changes: 2 additions & 0 deletions deploy/docker/Dockerfile-debian
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ RUN sudo gem install snappy
RUN sudo gem install fluent-plugin-sumologic_output \
&& sudo gem install fluent-plugin-carbon-v2 \
&& sudo gem install fluent-plugin-datapoint \
&& sudo gem install fluent-plugin-rewrite-tag-filter \
&& sudo gem install fluent-plugin-prometheus-format \
&& sudo gem install fluent-plugin-probuf

RUN sudo gem sources --clear-all \
Expand Down
16 changes: 16 additions & 0 deletions deploy/docker/fluent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@
tag "dummy"
dummy {"hello":"world"}
</source>
<source>
@type http
port 9888
<parse>
@type protobuf
</parse>
</source>
<match FOR_TEST_ONLY>
@type datapoint
</match>
<filter FOR_TEST_ONLY>
@type carbon_v2
</filter>
<filter FOR_TEST_ONLY>
@type prometheus_format
</filter>
<match **>
@type stdout
</match>
27 changes: 15 additions & 12 deletions deploy/test/test_docker.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
require 'test/unit'

class TestDocker < Test::Unit::TestCase
DOCKER_TAG = 'sumologic/kubernetes-fluentd'.freeze
CONTAINER_NAME = 'test-container'.freeze
DUMMY_OUTPUT = '"hello":"world"'.freeze
DUMMY_OUTPUT = 'dummy: {"hello":"world"}'.freeze

def setup
system("docker rm -f #{CONTAINER_NAME}", out: File::NULL, err: File::NULL)
Expand All @@ -13,23 +12,27 @@ def teardown
system("docker rm -f #{CONTAINER_NAME}", out: File::NULL, err: File::NULL)
end

def docker_tag
ENV['DOCKER_TAG'].nil? ? 'sumologic/kubernetes-fluentd' : ENV['DOCKER_TAG']
end

def test_docker_image_exist
result = `docker images`
assert result.include?(DOCKER_TAG)
assert result.include?(docker_tag)
end

def test_docker_image_runnable
id = `docker run -d --rm --name #{CONTAINER_NAME} #{DOCKER_TAG}:latest`
id = `docker run -d --rm --name #{CONTAINER_NAME} #{docker_tag}:latest`
assert !id.nil? && !id.empty?
[1..10].each do |i|
sleep 1
result = `docker ps --filter "name=#{CONTAINER_NAME}"`
assert(
result.include?(CONTAINER_NAME),
"container stopped after #{i} seconds"
)
end
sleep_time = 15
sleep sleep_time
result = `docker ps --filter "name=#{CONTAINER_NAME}"`
assert(
result.include?(CONTAINER_NAME),
"container stopped after #{sleep_time} seconds"
)
logs = `docker logs #{CONTAINER_NAME}`
puts logs
assert logs.include?(DUMMY_OUTPUT)
end
end
3 changes: 3 additions & 0 deletions fluent-plugin-prometheus-format/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source "https://rubygems.org"

gemspec
103 changes: 103 additions & 0 deletions fluent-plugin-prometheus-format/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# fluent-plugin-prometheus-format

[Fluentd](https://fluentd.org/) filter plugin to transform data points to prometheus format.

- All fields of the metric will be serialized as intrinsic tags (dimensions) in the prometheus format.
- Sample of Input

```json
{
"endpoint": "http-metrics",
"handler": "prometheus",
"instance": "172.20.36.191:10251",
"job": "kube-scheduler",
"namespace": "kube-system",
"kubernetes": {
"pod": {
"name": "kube-scheduler-ip-172-20-36-191.us-west-1.compute.internal"
},
"service": {
"name": "kube-scheduler"
}
},
"prometheus": "monitoring/prometheus-operator-prometheus",
"prometheus_replica": "prometheus-prometheus-operator-prometheus-0",
"service": "prometheus-operator-kube-scheduler",
"@metric": "http_request_size_bytes_sum",
"@timestamp": 1550862304339,
"@value": 1619905.0
}
```

- Sample of Output

```json
{
"message": "http_request_size_bytes_sum{endpoint=\"http-metrics\",handler=\"prometheus\",instance=\"172.20.36.191:10251\",job=\"kube-scheduler\",kubernetes.pod.name=\"kube-scheduler-ip-172-20-36-191.us-west-1.compute.internal\",kubernetes.service.name=\"kube-scheduler\",namespace=\"kube-system\",prometheus=\"monitoring/prometheus-operator-prometheus\",prometheus_replica=\"prometheus-prometheus-operator-prometheus-0\",service=\"prometheus-operator-kube-scheduler\",_origin=\"kubernetes\"} 1619905.0 1550862304339"
}
```

## Installation

### RubyGems

```sh
gem install fluent-plugin-prometheus-format
```

### Bundler

Add following line to your Gemfile:

```ruby
gem "fluent-plugin-prometheus-format"
```

And then execute:

```sh
bundle
```

## Configuration

### relabel (hash) (optional)

Relabel the field name in the input record.
For every (`key`, `value`) pair in the hash, the field named with `key` in the input record will be relabeled to `value`.
If `key` is not a field in the input record, it will be ignored.
If `value` is an empty string, the field will be removed from the record.

Default value: `{}`.

### inclusions (hash) (optional)

Whitelist of the records with regular expression matching on the field(s).
For __all__ (`key`, `value`) pairs in the hash, only following records will be included in the output:

- the value of field named with `key` matches the `value` (as regular expression).

Default value: `{}`.

### strict_inclusions (bool) (optional)

If `true`, records missing any field in keys of `inclusions` will be dropped.

Default value: `false`

### exclusions (hash) (optional)

Blacklist of the records with regular expression matching on the field(s).
For __any__ (`key`, `value`) pair in the hash, following records will be excluded in the output:

- the value of field named with `key` matches the `value` (as regular expression).

Default value: `{}`.

### strict_exclusions (bool) (optional)

If `true`, records missing any field in keys of `exclusions` will be dropped.

Default value: `false`

__NOTE__ inclusions/exclusions rules are applied after relabeling and flatten.
13 changes: 13 additions & 0 deletions fluent-plugin-prometheus-format/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "bundler"
Bundler::GemHelper.install_tasks

require "rake/testtask"

Rake::TestTask.new(:test) do |t|
t.libs.push("lib", "test")
t.test_files = FileList["test/**/test_*.rb"]
t.verbose = true
t.warning = true
end

task default: [:test]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)

Gem::Specification.new do |spec|
spec.name = "fluent-plugin-prometheus-format"
spec.version = "0.0.0"
spec.authors = ["Sumo Logic"]
spec.email = ["collection@sumologic.com"]

spec.summary = %q{Fluentd plugin for transfer data points to prometheus metrics format.}
spec.homepage = "https://github.com/SumoLogic/sumologic-kubernetes-collection"
spec.license = "Apache-2.0"

test_files, files = `git ls-files -z`.split("\x0").partition do |f|
f.match(%r{^(test|spec|features)/})
end
spec.files = files
spec.executables = files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = test_files
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rake", "~> 12.0"
spec.add_development_dependency "test-unit", "~> 3.0"
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
end