fluentd-server 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.env +5 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/API.md +21 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +9 -0
- data/Procfile +1 -0
- data/README.md +127 -0
- data/Rakefile +26 -0
- data/bench/bench.rb +83 -0
- data/bench/result.md +17 -0
- data/bin/fluentd-server +7 -0
- data/config.ru +15 -0
- data/config/unicorn.conf +20 -0
- data/db/migrate/20140512203133_create_posts.rb +14 -0
- data/db/schema.rb +25 -0
- data/fluentd-server.gemspec +43 -0
- data/lib/fluentd_server.rb +1 -0
- data/lib/fluentd_server/cli.rb +64 -0
- data/lib/fluentd_server/config.rb +27 -0
- data/lib/fluentd_server/decorator.rb +21 -0
- data/lib/fluentd_server/environments.rb +34 -0
- data/lib/fluentd_server/logger.rb +90 -0
- data/lib/fluentd_server/model.rb +10 -0
- data/lib/fluentd_server/version.rb +3 -0
- data/lib/fluentd_server/web.rb +101 -0
- data/lib/fluentd_server/web_helper.rb +91 -0
- data/public/css/bootstrap.min.css +7 -0
- data/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/public/fonts/glyphicons-halflings-regular.svg +229 -0
- data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/public/js/bootstrap.min.js +7 -0
- data/public/js/jquery-1.10.2.min.js +6 -0
- data/public/js/jquery-1.10.2.min.map +0 -0
- data/public/js/jquery.storageapi.min.js +2 -0
- data/spec/api_spec.rb +42 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/web_helper_spec.rb +27 -0
- data/spec/web_spec.rb +55 -0
- data/views/_navbar.slim +15 -0
- data/views/layout.slim +22 -0
- data/views/posts/create.slim +19 -0
- data/views/posts/edit.slim +23 -0
- data/views/posts/index.slim +9 -0
- metadata +363 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 23543f023f2b14f82abde08cceba1337e730c494
|
4
|
+
data.tar.gz: bb43d8d9a3686cc3e1cba3da52bf532438ba1cc9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b430c589ae0aaa6f102d36c98a61dc6230510ea590f528922f26d30a3e4b1511b07b323d7107b82ed417c00fab6734cb657ff7e4ceca60ef771d9a0766a0be64
|
7
|
+
data.tar.gz: 512e455f5e280674c272a992c8ea676323e207c7693eb597d460a9a6d3c88135b394d21b95872724a28c13f340d53538e5832f982b34132cf34644bc1dde0376
|
data/.env
ADDED
data/.gitignore
ADDED
data/API.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
## API
|
2
|
+
|
3
|
+
### GET /api/:name
|
4
|
+
|
5
|
+
Get the contents of Fluentd config whose name is :name.
|
6
|
+
Query parameters are replaced with variables in erb.
|
7
|
+
|
8
|
+
Supported query parameter formats are:
|
9
|
+
|
10
|
+
* var=value
|
11
|
+
|
12
|
+
* The variable `var` is replaced with its value in erb.
|
13
|
+
|
14
|
+
* var[]=value1&var[]=value2
|
15
|
+
|
16
|
+
* Array. The variable `var[idx]` such as `var[0]` and `var[1]` is replaced with its value in erb.
|
17
|
+
|
18
|
+
* var[key1]=value1&var[key2]=value2
|
19
|
+
|
20
|
+
* Hash. The variable `var[key]` such as `var['key1']` and `var['key2']` is replaced with its value in erb.
|
21
|
+
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec unicorn -E production -p $PORT -o $HOST -c config/unicorn.conf
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
# Fluentd Server
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/sonots/fluentd-server.png?branch=master)](http://travis-ci.org/sonots/fluentd-server)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/sonots/fluentd-server/badge.png?branch=master)](https://coveralls.io/r/sonots/fluentd-server?branch=master)
|
5
|
+
|
6
|
+
A Fluentd config distribution server
|
7
|
+
|
8
|
+
Demo: [http://fluentd-server.herokuapp.com](http://fluentd-server.herokuapp.com)
|
9
|
+
|
10
|
+
## What You Can Do
|
11
|
+
|
12
|
+
With Fluentd Server, you can manage fluentd configuration files centrally with `erb`.
|
13
|
+
|
14
|
+
For example, you may create a config post whose name is `worker` as:
|
15
|
+
|
16
|
+
```
|
17
|
+
<source>
|
18
|
+
type forward
|
19
|
+
port <%= port %>
|
20
|
+
</source>
|
21
|
+
|
22
|
+
<match **>
|
23
|
+
type stdout
|
24
|
+
</match>
|
25
|
+
```
|
26
|
+
|
27
|
+
Then you can download the config via an API whose uri is like `/api/worker?port=24224` where its query parameters are replaced with variables in the erb.
|
28
|
+
The downloaded contents should become as follows:
|
29
|
+
|
30
|
+
```
|
31
|
+
<source>
|
32
|
+
type forward
|
33
|
+
port 24224
|
34
|
+
</source>
|
35
|
+
|
36
|
+
<match **>
|
37
|
+
type stdout
|
38
|
+
</match>
|
39
|
+
```
|
40
|
+
|
41
|
+
## How to Use
|
42
|
+
|
43
|
+
The `include` directive of fluentd config supports `http`, so write just one line on your fluentd.conf as:
|
44
|
+
|
45
|
+
```
|
46
|
+
# /etc/fluentd.conf
|
47
|
+
include http://fqdn.to.fluentd-server/api/:name?port=24224
|
48
|
+
```
|
49
|
+
|
50
|
+
where :name is the name of your config post, so that it will download the real configuration from the Fluentd Server.
|
51
|
+
|
52
|
+
## Installation
|
53
|
+
|
54
|
+
Prerequisites
|
55
|
+
|
56
|
+
* SQLite
|
57
|
+
* Ruby 2.0 or later
|
58
|
+
|
59
|
+
### From Gem package
|
60
|
+
|
61
|
+
Easy steps on installation with gem and SQLite.
|
62
|
+
|
63
|
+
```bash
|
64
|
+
$ gem install fluentd-server
|
65
|
+
$ gem install sqlite3
|
66
|
+
$ fluentd-server new
|
67
|
+
$ cd fluentd-server
|
68
|
+
$ fluentd-server init # creates database scheme on SQLite
|
69
|
+
$ fluentd-server start
|
70
|
+
```
|
71
|
+
|
72
|
+
Then see `http://localhost:5126/`.
|
73
|
+
|
74
|
+
### From Git repository
|
75
|
+
|
76
|
+
Install from git repository.
|
77
|
+
|
78
|
+
```bash
|
79
|
+
$ git clone https://github.com/sonots/fluentd-server.git
|
80
|
+
$ cd fluentd-server
|
81
|
+
$ bundle
|
82
|
+
$ bundle exec fluentd-server init # creates database scheme on SQLite
|
83
|
+
$ bundle exec fluentd-server start
|
84
|
+
```
|
85
|
+
|
86
|
+
Then see `http://localhost:5126/`.
|
87
|
+
|
88
|
+
## Configuration
|
89
|
+
|
90
|
+
To configure fluentd-server, edit the `.env` file in the project root directory.
|
91
|
+
|
92
|
+
The default configuration is as follows:
|
93
|
+
|
94
|
+
```
|
95
|
+
PORT=5126
|
96
|
+
HOST=0.0.0.0
|
97
|
+
# DATABASE_URL=sqlite3:data/fluentd_server.db
|
98
|
+
# LOG_PATH=log/application.log
|
99
|
+
# LOG_LEVEL=warn
|
100
|
+
```
|
101
|
+
|
102
|
+
## HTTP API
|
103
|
+
|
104
|
+
See [API.md](API.md).
|
105
|
+
|
106
|
+
## ToDo
|
107
|
+
|
108
|
+
* Local file storage
|
109
|
+
|
110
|
+
* Saving and loading conf from localfiles rather than DB would be nice because it makes possible to manage conf with git
|
111
|
+
* Fluentd Server should cache them on memory, and refresh caches by detecting files are updated
|
112
|
+
|
113
|
+
## ChangeLog
|
114
|
+
|
115
|
+
See [CHANGELOG.md](CHANGELOG.md) for details.
|
116
|
+
|
117
|
+
## Contributing
|
118
|
+
|
119
|
+
1. Fork it
|
120
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
121
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
122
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
123
|
+
5. Create new [Pull Request](../../pull/new/master)
|
124
|
+
|
125
|
+
## Copyright
|
126
|
+
|
127
|
+
Copyright (c) 2014 Naotoshi Seo. See [LICENSE](LICENSE) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
5
|
+
t.rspec_opts = ["-c", "-f progress"] # '--format specdoc'
|
6
|
+
t.pattern = 'spec/**/*_spec.rb'
|
7
|
+
end
|
8
|
+
|
9
|
+
lib = File.expand_path('../lib', __FILE__)
|
10
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
11
|
+
require 'dotenv/tasks'
|
12
|
+
require 'fluentd_server/config'
|
13
|
+
|
14
|
+
require 'sinatra/activerecord/rake'
|
15
|
+
|
16
|
+
task :console => :dotenv do
|
17
|
+
require "fluentd_server"
|
18
|
+
require 'irb'
|
19
|
+
# require 'irb/completion'
|
20
|
+
ARGV.clear
|
21
|
+
IRB.start
|
22
|
+
end
|
23
|
+
task :c => :console
|
24
|
+
|
25
|
+
task :test => :spec
|
26
|
+
task :default => :spec
|
data/bench/bench.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'parallel'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
def main
|
7
|
+
requests = 20000 # number of requests to perform
|
8
|
+
concurrency = 126 # number of multiple requests to make
|
9
|
+
name = 'worker'
|
10
|
+
puts "requests = #{requests}"
|
11
|
+
puts "concurrency = #{concurrency}"
|
12
|
+
|
13
|
+
client = Client.new("http://localhost:5126")
|
14
|
+
|
15
|
+
duration = elapsed_time do
|
16
|
+
Parallel.each_with_index([name]*requests, :in_processes => concurrency) do |name, i|
|
17
|
+
puts "processing #{i}" if i % 1000 == 0
|
18
|
+
res = client.get(name)
|
19
|
+
puts 'error' unless res.code == '200'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
req_per_sec = ( duration > 0 ) ? requests/duration : 0
|
24
|
+
puts "req/sec = #{req_per_sec}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def elapsed_time(&block)
|
28
|
+
s = Time.now
|
29
|
+
yield
|
30
|
+
Time.now - s
|
31
|
+
end
|
32
|
+
|
33
|
+
class Client
|
34
|
+
attr_reader :base_uri
|
35
|
+
attr_reader :host
|
36
|
+
attr_reader :port
|
37
|
+
attr_accessor :debug_dev
|
38
|
+
attr_accessor :open_timeout
|
39
|
+
attr_accessor :read_timeout
|
40
|
+
attr_accessor :verify_ssl
|
41
|
+
attr_accessor :keepalive
|
42
|
+
|
43
|
+
def initialize(base_uri = 'http://127.0.0.1:5126', opts = {})
|
44
|
+
@base_uri = base_uri
|
45
|
+
|
46
|
+
URI.parse(base_uri).tap {|uri|
|
47
|
+
@host = uri.host
|
48
|
+
@port = uri.port
|
49
|
+
@use_ssl = uri.scheme == 'https'
|
50
|
+
}
|
51
|
+
@debug_dev = opts['debug_dev'] # IO object such as STDOUT
|
52
|
+
@open_timeout = opts['open_timeout'] # 60
|
53
|
+
@read_timeout = opts['read_timeout'] # 60
|
54
|
+
@verify_ssl = opts['verify_ssl']
|
55
|
+
@keepalive = opts['keepalive']
|
56
|
+
end
|
57
|
+
|
58
|
+
def http_connection
|
59
|
+
Net::HTTP.new(@host, @port).tap {|http|
|
60
|
+
http.use_ssl = @use_ssl
|
61
|
+
http.open_timeout = @open_timeout if @open_timeout
|
62
|
+
http.read_timeout = @read_timeout if @read_timeout
|
63
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_ssl
|
64
|
+
http.set_debug_output(@debug_dev) if @debug_dev
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_request(path, extheader = {})
|
69
|
+
Net::HTTP::Get.new(path).tap {|req|
|
70
|
+
req['Host'] = @host
|
71
|
+
req['Connection'] = 'Keep-Alive' if @keepalive
|
72
|
+
extheader.each {|key, value| req[key] = value }
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def get(name)
|
77
|
+
path = "/api/#{name}"
|
78
|
+
req = get_request(path)
|
79
|
+
@res = http_connection.start {|http| http.request(req) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
main
|
data/bench/result.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
The conf body as followings, would be too small to evaluate:
|
2
|
+
|
3
|
+
```
|
4
|
+
<source>
|
5
|
+
type forward
|
6
|
+
port <%= port %>
|
7
|
+
</source>
|
8
|
+
```
|
9
|
+
|
10
|
+
| # of requests | concurrency | server | # of workers | req/sec |
|
11
|
+
|---------------|-------------|---------|--------------|---------|
|
12
|
+
|20000 |126 | unicorn | 1 |865.07 |
|
13
|
+
|20000 |126 | unicorn | 12 |4116.78 |
|
14
|
+
|20000 |126 | puma | 1 |634.20|
|
15
|
+
|20000 |126 | puma | 12 |3765.66 |
|
16
|
+
|
17
|
+
Let's use unicorn
|
data/bin/fluentd-server
ADDED
data/config.ru
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "sinatra"
|
3
|
+
require "fluentd_server"
|
4
|
+
require "fluentd_server/web"
|
5
|
+
|
6
|
+
## Unicorn self-process killer
|
7
|
+
#require 'unicorn/worker_killer'
|
8
|
+
#
|
9
|
+
## Max requests per worker
|
10
|
+
#use Unicorn::WorkerKiller::MaxRequests, 3072, 4096
|
11
|
+
#
|
12
|
+
## Max memory size (RSS) per worker
|
13
|
+
#use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2))
|
14
|
+
|
15
|
+
run FluentdServer::Web
|
data/config/unicorn.conf
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
worker_processes 1
|
2
|
+
# timeout 6000
|
3
|
+
# preload_app true
|
4
|
+
|
5
|
+
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
|
6
|
+
|
7
|
+
before_fork do |server, worker|
|
8
|
+
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
|
9
|
+
|
10
|
+
old_pid = "#{server.config[:pid]}.oldbin"
|
11
|
+
if old_pid != server.pid
|
12
|
+
begin
|
13
|
+
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
|
14
|
+
Process.kill(sig, File.read(old_pid).to_i)
|
15
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
sleep 1
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreatePosts < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :posts do |t|
|
4
|
+
t.string :name
|
5
|
+
t.text :body
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
add_index :posts, :name, length: 255, unique: true # explicit length is required for MySQL
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :posts
|
13
|
+
end
|
14
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20140512203133) do
|
15
|
+
|
16
|
+
create_table "posts", force: true do |t|
|
17
|
+
t.string "name"
|
18
|
+
t.text "body"
|
19
|
+
t.datetime "created_at"
|
20
|
+
t.datetime "updated_at"
|
21
|
+
end
|
22
|
+
|
23
|
+
add_index "posts", ["name"], name: "index_posts_on_name", unique: true
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fluentd_server/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fluentd-server"
|
8
|
+
spec.version = FluentdServer::VERSION
|
9
|
+
spec.authors = ["Naotoshi Seo"]
|
10
|
+
spec.email = ["sonots@gmail.com"]
|
11
|
+
spec.description = %q{Fluentd config distribution server}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = "https://github.com/sonots/fluentd-server"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "capybara"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "pry-nav"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
|
28
|
+
spec.add_runtime_dependency "dotenv"
|
29
|
+
spec.add_runtime_dependency "foreman"
|
30
|
+
spec.add_runtime_dependency "thor"
|
31
|
+
|
32
|
+
spec.add_runtime_dependency "sinatra"
|
33
|
+
spec.add_runtime_dependency "activerecord"
|
34
|
+
spec.add_runtime_dependency "sinatra-contrib"
|
35
|
+
spec.add_runtime_dependency "sinatra-activerecord"
|
36
|
+
spec.add_runtime_dependency 'sinatra-flash'
|
37
|
+
spec.add_runtime_dependency 'sinatra-redirect-with-flash'
|
38
|
+
spec.add_runtime_dependency 'sinatra-decorator'
|
39
|
+
spec.add_runtime_dependency 'slim'
|
40
|
+
spec.add_runtime_dependency "unicorn"
|
41
|
+
spec.add_runtime_dependency "unicorn-worker-killer"
|
42
|
+
# spec.add_runtime_dependency 'sqlite3'
|
43
|
+
end
|