Skip to content

Instantly share code, notes, and snippets.

@suzukaze
Forked from frsyuki/example.sh
Created September 7, 2013 02:50
Show Gist options
  • Save suzukaze/6472406 to your computer and use it in GitHub Desktop.
Save suzukaze/6472406 to your computer and use it in GitHub Desktop.
$ ruby fluent-doc fluent-plugin-mongo 2>/dev/null
<source>
type mongo_tail
# [nil]
database string (required)
# [nil]
collection string (required)
# [nil]
host string (optional; default="localhost")
# [nil]
port integer (optional; default=27017)
# [nil]
wait_time integer (optional; default=1)
# [nil]
tag string (optional; default=nil)
# [nil]
tag_key string (optional; default=nil)
# [nil]
time_key string (optional; default=nil)
# [nil]
time_format string (optional; default=nil)
# [" To store last ObjectID"]
id_store_file string (optional; default=nil)
</source>
<match **>
type mongo
# [nil]
database string (required)
# [nil]
collection string (optional; default="untagged")
# [nil]
host string (optional; default="localhost")
# [nil]
port integer (optional; default=27017)
# [nil]
ignore_invalid_record bool (optional; default=false)
# [nil]
disable_collection_check bool (optional; default=nil)
# [nil]
exclude_broken_fields string (optional; default=nil)
# [nil]
write_concern integer (optional; default=nil)
# [" tag mapping mode"]
tag_mapped bool (optional; default=false)
# [nil]
remove_tag_prefix string (optional; default=nil)
</match **>
<match **>
type mongo_replset
# [nil]
nodes string (required)
# [nil]
name string (optional; default=nil)
# [nil]
read string (optional; default=nil)
# [nil]
refresh_mode string (optional; default=nil)
# [nil]
refresh_interval integer (optional; default=nil)
# [nil]
num_retries integer (optional; default=60)
# [" disable single node configuration"]
host string (optional; default=nil)
# [nil]
port integer (optional; default=nil)
</match **>
<match **>
type mongo_tag_collection
# [nil]
collection string (optional; default="untagged")
</match **>
#!/usr/bin/env ruby
require 'optparse'
op = OptionParser.new
op.banner += " <fluent-plugin-xzy>"
define_singleton_method(:usage) do |msg|
puts op.to_s
puts "error: #{msg}" if msg
exit 1
end
begin
op.parse!(ARGV)
if ARGV.length != 1
usage nil
end
gem_name = ARGV[0]
rescue
usage $!.to_s
end
require 'gems'
require 'httpclient'
require 'fileutils'
gem_info = Gems.info(gem_name)
name = gem_info['name']
version = gem_info['version']
$stderr.puts "Downloading #{name}-#{version}"
workdir = "tmp/#{name}-#{version}"
FileUtils.rm_rf workdir
FileUtils.mkdir_p workdir
http = HTTPClient.new
File.open("#{workdir}.gem", 'wb') do |f|
http.get_content("https://rubygems.org/downloads/#{name}-#{version}.gem") do |chunk|
f.write chunk
end
end
Dir.chdir(workdir) do
system("tar", "xf", "../#{name}-#{version}.gem")
system("tar", "xf", "data.tar.gz")
end
class Context
def self.create
c = Class.new(Context)
# Plugin
pl = Plugin.new
c.const_set(:Plugin, pl)
# Fluent::Plugin
fluent = Module.new
fluent.const_set(:Plugin, pl)
c.const_set(:Fluent, fluent)
c.new(pl)
end
def initialize(plugin)
@plugin = plugin
end
attr_reader :parameter
def type
@plugin.type
end
def name
@plugin.name
end
def config_param(name, *args, &block)
opts = {}
args.each {|a|
if a.is_a?(Symbol)
opts[:type] = a
elsif a.is_a?(Hash)
opts.merge!(a)
else
raise ArgumentError, "wrong number of arguments (#{1+args.length} for #{block ? 2 : 3})"
end
}
type = opts[:type] || :unknown
required = !opts.has_key?(:default)
default_value = opts[:default]
@parameter = [name, type, required, default_value]
end
class Plugin
attr_reader :type, :name
def register_input(type, klass)
@type = :input
@name = type
end
def register_output(type, klass)
@type = :output
@name = type
end
def register_buffer(type, klass)
@type = :buffer
@name = type
end
end
end
class Doc < Struct.new(:gem_name, :type, :name, :parameters)
end
docs = []
files = Dir["#{workdir}/lib/fluent/plugin/{in,out,buf}_*.rb"]
files.each do |file|
data = File.read(file)
type = nil
name = nil
parameters = []
data.scan(/^\s*(?:Fluent::)?Plugin.register_.*$/) do |line|
begin
ctx = Context.create
ctx.instance_eval(line)
type = ctx.type
name = ctx.name
rescue => e
STDERR.puts e
end
end
data.scan(/^\s*config_param.*$/).each do |line|
begin
indent = line[/^\s*/]
comments = data.scan(/(?:#{Regexp.escape(indent)}\#([^\n]*)\n)*#{Regexp.escape(line)}/m)
if line =~ /do\s*\|.*$/
line << "\nend"
elsif line =~ /\{\s*\|[^\{]$/
line << "\n}"
end
ctx = Context.create
ctx.instance_eval(line)
parameters << ctx.parameter + [comments]
rescue => e
STDERR.puts e
end
end
docs << Doc.new(gem_name, type, name, parameters)
end
docs.each do |doc|
puts "#{doc.gem_name}:"
if doc.type == :input
puts "<source>"
else
puts "<match **>"
end
puts " type #{doc.name}"
doc.parameters.each do |(name,type,required,default_value,comments)|
puts ""
comments.each do |com|
puts " # #{com}"
end
if required
puts " #{name} #{type} (required)"
else
puts " #{name} #{type} (optional; default=#{default_value.inspect})"
end
end
if doc.type == :input
puts "</source>"
else
puts "</match **>"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment