通过TCP向Logstash发送数据

11

我在使用一个简单的Java应用程序向我的Logstash实例发送日志数据时遇到了一些问题。对于我的使用情况,我试图避免使用log4j、logback等工具,而是通过一个原始的TCP套接字将JSON事件分批处理并分行发送。这样做的原因是我希望通过AWS Lambda函数将数据发送到Logstash,这意味着将日志存储到磁盘上可能行不通。

我的Logstash配置文件如下:

input {
  tcp {
        port => 5400
        codec => json
  }
}
filter{
  json{
    source => "message"
  }
}
output {
   elasticsearch {
      host => "localhost"
      protocol => "http"
      index => "someIndex"
   }
}

目前我的Java代码只是打开一个TCP套接字到Logstash服务器并直接发送事件。

Socket socket = new Socket("logstash-hostname", 5400);
DataOutputStream os = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
os.writeBytes("{\"message\": {\"someField\":\"someValue\"} }");
os.flush();
socket.close();
应用程序与logstash主机进行连接正常(如果logstash没有启动,则在连接时会抛出异常),但在我们的ES集群中没有显示任何事件。 如何解决这个问题,非常感谢您提供的任何想法!在logstash.err、logstash.log或logstash.stdout中没有看到任何相关日志,指出可能出了什么问题。

如果您将输入定义为json,则不需要运行json过滤器。要查看logstash正在执行的操作,请添加一个“stdout {codec => rubydebug}”输出段,并查看stdout日志中出现了什么。 - Alain Collins
遇到了相同的问题...似乎是tcp被netcat监听了...但是logstash没有接收或处理输入?!? - daparic
3个回答

27

问题在于你的数据已经在输入时反序列化了,而你现在正在尝试在过滤器上再次进行反序列化。只需删除json过滤器即可。

这是我重新创建您的场景的方法:

# the json input
root@monitoring:~# cat tmp.json 
{"message":{"someField":"someValue"}}


# the logstash configuration file
root@monitoring:~# cat /etc/logstash/conf.d/test.conf
input {
  tcp {
    port => 5400
    codec => json
  }
}

filter{
}

output {
   stdout {
     codec => rubydebug
   }
}


# starting the logstash server
/opt/logstash/bin/logstash -f /etc/logstash/conf.d/test.conf


# sending the json to logstash with netcat
nc localhost 5400 <  tmp.json

# the logstash output via stdout
{
       "message" => {
        "someField" => "someValue"
    },
      "@version" => "1",
    "@timestamp" => "2016-02-02T13:31:18.703Z",
          "host" => "0:0:0:0:0:0:0:1",
          "port" => 56812
}
希望对你有所帮助,

2
不要忘记在JSON末尾添加\n
os.writeBytes("{\"bossMessage\": {\"someField\":\"someValue\"} }" + '\n');

0
我发现在TCP输入节点上使用编解码器时,JSON解析会因未知原因而失败。移除TCP输入上的编解码器并仅添加过滤器解决了我的JSON解析问题。
   input {
  tcp {
        port => 5400
  }
}
filter{
  json{
    source => "message"
  }
}
output {
   elasticsearch {
      host => "localhost"
      protocol => "http"
      index => "someIndex"
   }
}

同时,我一次性写入整个字符串,不在消息中发送"\n",否则Logstash将只收到一个带有代码"\r"的空记录。

PrintWriter pw = new PrintWriter(os);
pw.println(stringOut);
pw.flush();

这将在流的末尾附加“\r”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接