Class: Fluent::Config::V1Parser
- Inherits:
-
LiteralParser
- Object
- BasicParser
- LiteralParser
- Fluent::Config::V1Parser
- Defined in:
- lib/fluent/config/v1_parser.rb
Constant Summary collapse
- ELEMENT_NAME =
/[a-zA-Z0-9_]+/- ELEM_SYMBOLS =
['match', 'source', 'filter', 'system']
- RESERVED_PARAMS =
%W(@type @id @label @log_level)
Constants inherited from BasicParser
BasicParser::LINE_END, BasicParser::LINE_END_WITHOUT_SPACING_AND_COMMENT, BasicParser::SPACING, BasicParser::SPACING_WITHOUT_COMMENT, BasicParser::ZERO_OR_MORE_SPACING
Class Method Summary collapse
Instance Method Summary collapse
-
#error_sample ⇒ Object
override.
- #eval_include(attrs, elems, uri) ⇒ Object
-
#initialize(strscan, include_basepath, fname, eval_context, on_file_parsed: nil) ⇒ V1Parser
constructor
A new instance of V1Parser.
- #parse! ⇒ Object
- #parse_element(root_element, elem_name, attrs = {}, elems = []) ⇒ Object
- #parse_include(attrs, elems) ⇒ Object
Methods inherited from LiteralParser
#eval_embedded_code, #eval_escape_char, #parse_literal, #scan_double_quoted_string, #scan_embedded_code, #scan_json, #scan_nonquoted_string, #scan_single_quoted_string, #scan_string, unescape_char
Methods inherited from BasicParser
#check, #eof?, #getch, #line_end, #parse_error!, #prev_match, #scan, #skip, #spacing, #spacing_without_comment
Methods included from BasicParser::ClassMethods
#def_literal, #def_symbol, #symbol
Constructor Details
#initialize(strscan, include_basepath, fname, eval_context, on_file_parsed: nil) ⇒ V1Parser
Returns a new instance of V1Parser.
36 37 38 39 40 41 42 |
# File 'lib/fluent/config/v1_parser.rb', line 36 def initialize(strscan, include_basepath, fname, eval_context, on_file_parsed: nil) super(strscan, eval_context) @include_basepath = include_basepath @fname = fname @logger = defined?($log) ? $log : nil @on_file_parsed = on_file_parsed end |
Class Method Details
.parse(data, fname, basepath = Dir.pwd, eval_context = nil, on_file_parsed: nil) ⇒ Object
30 31 32 33 34 |
# File 'lib/fluent/config/v1_parser.rb', line 30 def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil, on_file_parsed: nil) ss = StringScanner.new(data) ps = V1Parser.new(ss, basepath, fname, eval_context, on_file_parsed: on_file_parsed) ps.parse! end |
Instance Method Details
#error_sample ⇒ Object
override
195 196 197 |
# File 'lib/fluent/config/v1_parser.rb', line 195 def error_sample "#{@fname} #{super}" end |
#eval_include(attrs, elems, uri) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/fluent/config/v1_parser.rb', line 153 def eval_include(attrs, elems, uri) # replace space(s)(' ') with '+' to prevent invalid uri due to space(s). # See: https://github.com/fluent/fluentd/pull/2780#issuecomment-576081212 u = URI.parse(uri.tr(' ', '+')) if u.scheme == 'file' || (!u.scheme.nil? && u.scheme.length == 1) || u.path == uri.tr(' ', '+') # file path # When the Windows absolute path then u.scheme.length == 1 # e.g. C: path = URI.decode_www_form_component(u.path) if path[0] != ?/ pattern = File.("#{@include_basepath}/#{path}") else pattern = path end Dir.glob(pattern).sort.each { |entry| basepath = File.dirname(entry) fname = File.basename(entry) suspicious_backup_extensions = %w(bak old backup orig prev conf tmp temp debug wip) if path.end_with?('*.conf') and suspicious_backup_extensions.any? { |ext| fname.end_with?(".#{ext}.conf", "_#{ext}.conf") } @logger.warn "There is a possibility that '@include #{uri}' includes duplicated backed-up config file such as <#{fname}>" if @logger end data = File.read(entry) data.force_encoding('UTF-8') ss = StringScanner.new(data) V1Parser.new(ss, basepath, fname, @eval_context, on_file_parsed: @on_file_parsed).parse_element(true, nil, attrs, elems) } else require 'open-uri' basepath = '/' fname = path data = u.open { |f| f.read } data.force_encoding('UTF-8') ss = StringScanner.new(data) V1Parser.new(ss, basepath, fname, @eval_context, on_file_parsed: @on_file_parsed).parse_element(true, nil, attrs, elems) end rescue SystemCallError => e cpe = ConfigParseError.new("include error #{uri} - #{e}") cpe.set_backtrace(e.backtrace) raise cpe end |
#parse! ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/fluent/config/v1_parser.rb', line 44 def parse! attrs, elems = parse_element(true, nil) root = Element.new('ROOT', '', attrs, elems) root.v1_config = true spacing unless eof? parse_error! "expected EOF" end return root end |
#parse_element(root_element, elem_name, attrs = {}, elems = []) ⇒ Object
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/fluent/config/v1_parser.rb', line 60 def parse_element(root_element, elem_name, attrs = {}, elems = []) while true spacing if eof? if root_element break end parse_error! "expected end tag '</#{elem_name}>' but got end of file" end if skip(/\<\//) e_name = scan(ELEMENT_NAME) spacing unless skip(/\>/) parse_error! "expected character in tag name" end unless line_end parse_error! "expected end of line after end tag" end if e_name != elem_name parse_error! "unmatched end tag" end break elsif skip(/\</) e_name = scan(ELEMENT_NAME) spacing e_arg = scan_string(/(?:#{ZERO_OR_MORE_SPACING}\>)/o) spacing unless skip(/\>/) parse_error! "expected '>'" end unless line_end parse_error! "expected end of line after tag" end e_arg ||= '' # call parse_element recursively e_attrs, e_elems = parse_element(false, e_name) new_e = Element.new(e_name, e_arg, e_attrs, e_elems) new_e.v1_config = true elems << new_e elsif root_element && skip(/(\@include|include)#{SPACING}/o) if !prev_match.start_with?('@') @logger.warn "'include' is deprecated. Use '@include' instead" if @logger end parse_include(attrs, elems) else k = scan_string(SPACING) spacing_without_comment if prev_match.include?("\n") || eof? # support 'tag_mapped' like "without value" configuration attrs[k] = "" else if k == '@include' parse_include(attrs, elems) elsif RESERVED_PARAMS.include?(k) v = parse_literal unless line_end parse_error! "expected end of line" end attrs[k] = v else if k.start_with?('@') if root_element || ELEM_SYMBOLS.include?(elem_name) parse_error! "'@' is the system reserved prefix. Don't use '@' prefix parameter in the configuration: #{k}" else # TODO: This is for backward compatibility. It will throw an error in the future. @logger.warn "'@' is the system reserved prefix. It works in the nested configuration for now but it will be rejected: #{k}" if @logger end end v = parse_literal unless line_end parse_error! "expected end of line" end attrs[k] = v end end end end @on_file_parsed&.call(File.(File.join(@include_basepath, @fname))) if root_element return attrs, elems end |
#parse_include(attrs, elems) ⇒ Object
147 148 149 150 151 |
# File 'lib/fluent/config/v1_parser.rb', line 147 def parse_include(attrs, elems) uri = scan_string(LINE_END) eval_include(attrs, elems, uri) line_end end |