Class: Fluent::YohoushiOutput

Inherits:
BufferedOutput
  • Object
show all
Defined in:
lib/fluent/plugin/out_yohoushi.rb

Defined Under Namespace

Classes: PlaceholderExpander, RubyPlaceholderExpander

Constant Summary collapse

MAPPING_MAX_NUM =
20
KEY_MAX_NUM =
20

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeYohoushiOutput



8
9
10
11
12
13
# File 'lib/fluent/plugin/out_yohoushi.rb', line 8

def initialize
  super
  require 'socket'
  require 'multiforecast-client'
  require 'yohoushi-client'
end

Instance Attribute Details

#clientObject (readonly)

for test



47
48
49
# File 'lib/fluent/plugin/out_yohoushi.rb', line 47

def client
  @client
end

#key_patternObject (readonly)

Returns the value of attribute key_pattern.



50
51
52
# File 'lib/fluent/plugin/out_yohoushi.rb', line 50

def key_pattern
  @key_pattern
end

#key_pattern_pathObject (readonly)

Returns the value of attribute key_pattern_path.



51
52
53
# File 'lib/fluent/plugin/out_yohoushi.rb', line 51

def key_pattern_path
  @key_pattern_path
end

#keysObject (readonly)

Returns the value of attribute keys.



49
50
51
# File 'lib/fluent/plugin/out_yohoushi.rb', line 49

def keys
  @keys
end

#mappingObject (readonly)

Returns the value of attribute mapping.



48
49
50
# File 'lib/fluent/plugin/out_yohoushi.rb', line 48

def mapping
  @mapping
end

Instance Method Details

#configure(conf) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/fluent/plugin/out_yohoushi.rb', line 53

def configure(conf)
  super

  if @base_uri
    @client = Yohoushi::Client.new(@base_uri)
  else
    @mapping = {}
    (1..MAPPING_MAX_NUM).each do |i|
      next unless conf["mapping#{i}"]
      from, to = conf["mapping#{i}"].split(/ +/, 2)
      raise ConfigError, "mapping#{i} does not contain 2 parameters" unless to
      @mapping[from] = to
    end
    @client = MultiForecast::Client.new('mapping' => @mapping) unless @mapping.empty?
  end
  raise ConfigError, "Either of `base_uri` or `mapping1` must be specified" unless @client

  if @key_pattern
    key_pattern, @key_pattern_path = @key_pattern.split(/ +/, 2)
    raise ConfigError, "key_pattern does not contain 2 parameters" unless @key_pattern_path
    @key_pattern = Regexp.compile(key_pattern)
  else
    @keys = {}
    (1..KEY_MAX_NUM).each do |i|
      next unless conf["key#{i}"] 
      key, path = conf["key#{i}"].split(/ +/, 2)
      raise ConfigError, "key#{i} does not contain 2 parameters" unless path
      @keys[key] = path
    end
  end
  raise ConfigError, "Either of `key_pattern` or `key1` must be specified" if (@key_pattern.nil? and @keys.empty?)

  @placeholder_expander =
    if @enable_ruby
      # require utilities which would be used in ruby placeholders
      require 'pathname'
      require 'uri'
      require 'cgi'
      RubyPlaceholderExpander.new
    else
      PlaceholderExpander.new
    end

  @hostname = Socket.gethostname
rescue => e
  raise ConfigError, "#{e.class} #{e.message} #{e.backtrace.first}"
end

#expand_placeholder(value, time, record, opts) ⇒ Object



157
158
159
160
# File 'lib/fluent/plugin/out_yohoushi.rb', line 157

def expand_placeholder(value, time, record, opts)
  @placeholder_expander.prepare_placeholders(time, record, opts)
  @placeholder_expander.expand(value)
end

#format(tag, time, record) ⇒ Object



119
120
121
# File 'lib/fluent/plugin/out_yohoushi.rb', line 119

def format(tag, time, record)
  [tag, time, record].to_msgpack
end

#post(path, number) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/fluent/plugin/out_yohoushi.rb', line 109

def post(path, number)
  if @enable_float_number
    @client.post_graph(path, { 'number' => number.to_f, 'mode' => @mode.to_s })
  else
    @client.post_graph(path, { 'number' => number.to_i, 'mode' => @mode.to_s })
  end
rescue => e
  $log.warn "out_yohoushi: #{e.class} #{e.message} #{path} #{e.backtrace.first}"
end

#shutdownObject



105
106
107
# File 'lib/fluent/plugin/out_yohoushi.rb', line 105

def shutdown
  super
end

#startObject



101
102
103
# File 'lib/fluent/plugin/out_yohoushi.rb', line 101

def start
  super
end

#tag_prefix(tag_parts) ⇒ Object



162
163
164
165
166
167
168
169
# File 'lib/fluent/plugin/out_yohoushi.rb', line 162

def tag_prefix(tag_parts)
  return [] if tag_parts.empty?
  tag_prefix = [tag_parts.first]
  1.upto(tag_parts.size-1).each do |i|
    tag_prefix[i] = "#{tag_prefix[i-1]}.#{tag_parts[i]}"
  end
  tag_prefix
end

#tag_suffix(tag_parts) ⇒ Object



171
172
173
174
175
176
177
178
179
# File 'lib/fluent/plugin/out_yohoushi.rb', line 171

def tag_suffix(tag_parts)
  return [] if tag_parts.empty?
  rev_tag_parts = tag_parts.reverse
  rev_tag_suffix = [rev_tag_parts.first]
  1.upto(tag_parts.size-1).each do |i|
    rev_tag_suffix[i] = "#{rev_tag_parts[i]}.#{rev_tag_suffix[i-1]}"
  end
  rev_tag_suffix.reverse
end

#write(chunk) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/fluent/plugin/out_yohoushi.rb', line 123

def write(chunk)
  chunk.msgpack_each do |tag, time, record|
    tag_parts = tag.split('.')
    tag_prefix = tag_prefix(tag_parts)
    tag_suffix = tag_suffix(tag_parts)
    placeholders = {
      'tag' => tag,
      'tags' => tag_parts, # for lower compatibility
      'tag_parts' => tag_parts,
      'tag_prefix' => tag_prefix,
      'tag_suffix' => tag_suffix,
      'hostname' => @hostname,
    }
    if @key_pattern
      record.each do |key, value|
        next unless key =~ @key_pattern
        placeholders['key'] = key
        path = expand_placeholder(@key_pattern_path, time, record, placeholders)
        post(path, value)
      end
    else # keys
      @keys.each do |key, path|
        next unless value = record[key]
        placeholders['key'] = key
        path = expand_placeholder(path, time, record, placeholders)
        post(path, value)
      end
    end
  end
rescue => e
  $log.warn "out_yohoushi: #{e.class} #{e.message} #{e.backtrace.first}"
  # Here, no raise of an error, so this BufferedOutput does not retry
end