elasticsearch,logstash,Ruby,elasticsearch,Logstash" /> elasticsearch,logstash,Ruby,elasticsearch,Logstash" />

Ruby 通过logstash将protobuf中的压缩字节字符串转换为格式化

Ruby 通过logstash将protobuf中的压缩字节字符串转换为格式化,ruby,elasticsearch,logstash,Ruby,elasticsearch,Logstash,我有一个protobuf,我正试图通过logstash输入。有些值看起来是二进制格式的: 通过rubydebug编解码器打印时 我得到的价值观如下: rData => '\xD8:\xC9$' 这似乎是因为通过protobuf模板具有: optional :bytes, :rData, 5 哪个。。。按照tin上的说明操作—将原始字节传递给logstash,logstash随后假设它们是文本 因此,rData行将解码为216.58.201.36,这是对www.google.com的响应

我有一个protobuf,我正试图通过logstash输入。有些值看起来是二进制格式的:

通过
rubydebug
编解码器打印时

我得到的价值观如下:

rData => '\xD8:\xC9$'
这似乎是因为通过
protobuf
模板具有:

optional :bytes, :rData, 5
哪个。。。按照tin上的说明操作—将原始字节传递给logstash,logstash随后假设它们是文本

因此,
rData
行将解码为
216.58.201.36
,这是对
www.google.com
的响应


如何在elasticsearch中将其转换为有用的格式

为了实现这一点,您需要自己编写一点ruby

但别担心,这比听起来容易,您可以将ruby内联到logstash配置文件中

第一:

  • 将输出编解码器设置为
    rubydebug
    ,这样它就可以打印数据结构——您需要它来确定需要哪些字段
因此,以我为例(为简洁起见剪掉):

我们对
rData
字段感兴趣

"socketProtocol" => 1,
    "@timestamp" => 2017-12-12T10:26:41.910Z,
   "requestorId" => "",
          "port" => 47788,
      "response" => {
            "rcode" => 0,
              "rrs" => [
        [0] {
             "rType" => 1,
             "rData" => "\xD8:\xC9$",
            "rClass" => 1,
             "rName" => "www.google.com.",
              "rTtl" => 300
        }
    ],
我们还有几个较长的
rData
字段示例,其中rubydebug中的值为:

"rData" => "*\x00\x14P@\t\b\v\x00\x00\x00\x00\x00\x00 \x04",
最终渲染为Elasticsearch,如下所示:

"rData": "*\u0000\u0014P@\t\b\u000b\u0000\u0000\u0000\u0000\u0000\u0000 \u0004",
因此,我们使用
event.get(“response”)
来提取它,这样我们就可以测试它的存在性(必要的,因为在我的用例中会有
response
字段,没有数据):

注意-这将测试
rData
值的长度,如果它是“长”的,则假定它是ipv6地址,格式为十六进制,如果它是短的,则假定它是ipv4,格式为传统的“点”四进制

然后,它添加到一个新的子字段,
response.decodedrdata
,这对于elasticsearch可能比嵌套任何更深的内容更有用

我们还有一个额外的代码片段来处理
/
/
messageId
字段的“字节”编码,该字段大体类似:

  ruby {
    code =>  
       #take to and from fields, and assume they're packed IP addresses. 
       #take messageId and convert to hex. 
       'event.set("from", event.get("from").unpack("C4").join("."));
        event.set("to", event.get("to").unpack("C4").join("."));
        event.set("messageId", event.get("messageId").unpack("H*").join(""));
       '
  }
  ruby {
    code =>  
       #take to and from fields, and assume they're packed IP addresses. 
       #take messageId and convert to hex. 
       'event.set("from", event.get("from").unpack("C4").join("."));
        event.set("to", event.get("to").unpack("C4").join("."));
        event.set("messageId", event.get("messageId").unpack("H*").join(""));
       '
  }