2026년 10월 7일 수요일

Logstash 필터 xml - 2nd

xml 필터는 xml 코드만을 인식한다.
filter {
 mutate {
  remove_field => ["@timestamp", "@version", "path", "host"]
 }

 xml {
  force_array => false
  source => "message"
  target => "event"
 }
}
[2026-10-06T23:32:51,999][WARN ][logstash.filters.xml     ][main] Error parsing xml with XmlSimple {source: "message", value: "Sep  3 13:29:14 rocky sysmon[1631]: <Event><System><Provider Name=\"Linux-Sysmon\" Guid=\"{ff032593-a8d3-4f13-b0d6-01fc615a0f97}\"/><EventID>1</EventID><Version>5</Version><Level>4</Level><Task>1</Task><Opcode>0</Opcode><Keywords>0x8000000000000000</Keywords><TimeCreated SystemTime=\"2026-09-03T04:29:14.717687000Z\"/><EventRecordID>244</EventRecordID><Correlation/><Execution ProcessID=\"1631\" ThreadID=\"1631\"/><Channel>Linux-Sysmon/Operational</Channel><Computer>rocky</Computer><Security UserId=\"0\"/></System><EventData><Data Name=\"RuleName\">-</Data><Data Name=\"UtcTime\">2026-09-03 04:29:14.722</Data><Data Name=\"ProcessGuid\">{10190b56-f79a-6a98-89bd-6677a8550000}</Data><Data Name=\"ProcessId\">2026</Data><Data Name=\"Image\">/usr/lib/systemd/systemd-userwork</Data><Data Name=\"FileVersion\">-</Data><Data Name=\"Description\">-</Data><Data Name=\"Product\">-</Data><Data Name=\"Company\">-</Data><Data Name=\"OriginalFileName\">-</Data><Data Name=\"CommandLine\">/usr/lib/systemd/systemd-userwork xxxxxxxxxxxxxxxx</Data><Data Name=\"CurrentDirectory\">/</Data><Data Name=\"User\">root</Data><Data Name=\"LogonGuid\">{10190b56-d9f0-6a98-0000-000000000000}</Data><Data Name=\"LogonId\">0</Data><Data Name=\"TerminalSessionId\">4294967295</Data><Data Name=\"IntegrityLevel\">no level</Data><Data Name=\"Hashes\">SHA1=3b0aef615e6e64d432d6e813c642a98fd5516cb1,MD5=3ef1ef384b1b35a31c7413c8be83a19e,SHA256=7500c4b7e7c6677c4004be01d0b37654948473d7c2ddbb681df8c2ccd08897f4</Data><Data Name=\"ParentProcessGuid\">{00000000-0000-0000-0000-000000000000}</Data><Data Name=\"ParentProcessId\">684</Data><Data Name=\"ParentImage\">-</Data><Data Name=\"ParentCommandLine\">-</Data><Data Name=\"ParentUser\">-</Data></EventData></Event>\r", exception: #<REXML::ParseException:"Malformed XML: Content at the start of the document (got 'Sep  3 13:29:14 rocky sysmon[1631]: ')\nLine: 1\nPosition: 43\nLast 80 unconsumed characters:\n<Event>">, backtrace: ["D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:517:in 'pull_event'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:249:in 'pull'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb:21:in 'parse'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb:468:in 'build'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb:105:in 'initialize'", "org/jruby/RubyClass.java:1023:in 'new'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:979:in 'parse'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:164:in 'xml_in'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:203:in 'xml_in'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/logstash-filter-xml-4.3.2/lib/logstash/filters/xml.rb:196:in 'filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:158:in 'do_filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:176:in 'block in multi_filter'", "org/jruby/RubyArray.java:2097:in 'each'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:173:in 'multi_filter'", "org/logstash/config/ir/compiler/AbstractFilterDelegatorExt.java:140:in 'multi_filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/java_pipeline.rb:352:in 'block in start_workers'"]}
{
    "message" => "Sep  3 13:29:14 rocky sysmon[1631]: <Event><System><Provider Name=\"Linux-Sysmon\" Guid=\"{ff032593-a8d3-4f13-b0d6-01fc615a0f97}\"/><EventID>1</EventID><Version>5</Version><Level>4</Level><Task>1</Task><Opcode>0</Opcode><Keywords>0x8000000000000000</Keywords><TimeCreated SystemTime=\"2026-09-03T04:29:14.717687000Z\"/><EventRecordID>244</EventRecordID><Correlation/><Execution ProcessID=\"1631\" ThreadID=\"1631\"/><Channel>Linux-Sysmon/Operational</Channel><Computer>rocky</Computer><Security UserId=\"0\"/></System><EventData><Data Name=\"RuleName\">-</Data><Data Name=\"UtcTime\">2026-09-03 04:29:14.722</Data><Data Name=\"ProcessGuid\">{10190b56-f79a-6a98-89bd-6677a8550000}</Data><Data Name=\"ProcessId\">2026</Data><Data Name=\"Image\">/usr/lib/systemd/systemd-userwork</Data><Data Name=\"FileVersion\">-</Data><Data Name=\"Description\">-</Data><Data Name=\"Product\">-</Data><Data Name=\"Company\">-</Data><Data Name=\"OriginalFileName\">-</Data><Data Name=\"CommandLine\">/usr/lib/systemd/systemd-userwork xxxxxxxxxxxxxxxx</Data><Data Name=\"CurrentDirectory\">/</Data><Data Name=\"User\">root</Data><Data Name=\"LogonGuid\">{10190b56-d9f0-6a98-0000-000000000000}</Data><Data Name=\"LogonId\">0</Data><Data Name=\"TerminalSessionId\">4294967295</Data><Data Name=\"IntegrityLevel\">no level</Data><Data Name=\"Hashes\">SHA1=3b0aef615e6e64d432d6e813c642a98fd5516cb1,MD5=3ef1ef384b1b35a31c7413c8be83a19e,SHA256=7500c4b7e7c6677c4004be01d0b37654948473d7c2ddbb681df8c2ccd08897f4</Data><Data Name=\"ParentProcessGuid\">{00000000-0000-0000-0000-000000000000}</Data><Data Name=\"ParentProcessId\">684</Data><Data Name=\"ParentImage\">-</Data><Data Name=\"ParentCommandLine\">-</Data><Data Name=\"ParentUser\">-</Data></EventData></Event>\r",
       "tags" => [
        [0] "_xmlparsefailure"
    ]
}

xml 코드를 제외한 로그 헤더를 삭제해야 함.

filter {
 mutate {
  remove_field => ["@timestamp", "@version", "path", "host"]
 }
 mutate {
  gsub => ["message", "[^<]+", ""]
  remove_field => ["@timeatamp", "@version", "path", "host"]
 }

 xml {
  force_array => false
  source => "message"
  target => "event"
 }
}
[2026-10-06T23:41:38,391][WARN ][logstash.filters.xml     ][main] Error parsing xml with XmlSimple {source: "message", value: "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", exception: #<ArgumentError: File does not exist: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.>, backtrace: ["D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:1004:in 'find_xml_file'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:168:in 'xml_in'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/xml-simple-1.1.9/lib/xmlsimple.rb:203:in 'xml_in'", "D:/ELK/v9/logstash-9.5.2/vendor/bundle/jruby/3.4.0/gems/logstash-filter-xml-4.3.2/lib/logstash/filters/xml.rb:196:in 'filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:158:in 'do_filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:176:in 'block in multi_filter'", "org/jruby/RubyArray.java:2097:in 'each'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/filters/base.rb:173:in 'multi_filter'", "org/logstash/config/ir/compiler/AbstractFilterDelegatorExt.java:140:in 'multi_filter'", "D:/ELK/v9/logstash-9.5.2/logstash-core/lib/logstash/java_pipeline.rb:352:in 'block in start_workers'"]}
{
    "message" => "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",
       "tags" => [
        [0] "_xmlparsefailure"
    ]
}

내가 뭘 잘못했을까? 전에 사용했던 정규표현식과 비교. mutate 필터의 gsub 옵션은 전체 검색 결과를 반환하는 global 수정자 사용이 기본.
 

global 수정자 해제는 안 되기 때문에 시작 위치를 고정해야 한다(..) 해봤던 작업인데도 실수 한 이유는 xml 데이터 만져본 경험이 아직 충분하지 않아서. 한 백 번 반복하면 실수 안 한다. 외워서 될 일이 아니라, 손에 익어야 되는 일이라는 얘기. 

솔직히 내가 이거 외울 수 있으면 그 능력으로 다른 거 한다. 관심과 적성, 그리고 곤조가 있어야 가능한 일. 시간 투자도 싫고, 외워지지도 않는다면 다른 적성 찾는 게 낫다.   

댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스