Configuring a Logstash TCP input enables applications and log shippers to push events directly over the network, which is useful for sources that cannot write to local files or need low-latency delivery.
The tcp input plugin binds to a host and port, turns each received message into an event, and applies a codec (such as json) to decode structured payloads before filters and outputs process the data.
A TCP listener is a reachable service endpoint, so an exposed port can become an unauthenticated log dropbox and cleartext transport can leak log contents; restrict access by binding to the correct interface, allow-listing at the firewall, and using TLS when traffic crosses untrusted networks.
Steps to configure a Logstash TCP input:
- Create a pipeline configuration file at /etc/logstash/conf.d/25-tcp-input.conf.
input { tcp { id => "tcp-json-5000" host => "0.0.0.0" port => 5000 codec => json tags => ["tcp"] } } output { elasticsearch { hosts => ["http://elasticsearch.example.net:9200"] index => "tcp-events-%{+YYYY.MM.dd}" } }Binding to 0.0.0.0 accepts connections from any reachable network; restrict TCP/5000 to trusted senders or enable TLS before exposing the listener outside a trusted segment.
- Test the pipeline configuration.
$ sudo /usr/share/logstash/bin/logstash --path.settings /etc/logstash --config.test_and_exit ##### snipped ##### Configuration OK
Fix any reported errors before restarting, as invalid pipeline syntax prevents Logstash from starting cleanly.
- Restart the Logstash service.
$ sudo systemctl restart logstash
- Verify the Logstash service is running without startup errors.
$ sudo systemctl status logstash --no-pager -n 20 ● logstash.service - logstash Loaded: loaded (/usr/lib/systemd/system/logstash.service; enabled; preset: enabled) Active: active (running) since Wed 2026-01-07 11:45:22 UTC; 15s ago ##### snipped ##### - Verify Logstash is listening on port 5000.
$ sudo ss -lntp | grep -F ':5000' LISTEN 0 1024 *:5000 *:* users:(("java",pid=22424,fd=309)) - Send a newline-terminated JSON test event to the TCP input.
$ printf '{"message":"tcp input test","level":"info","app":"demo"}\n' | nc -w 2 127.0.0.1 5000The json codec expects one complete JSON object per message, and line-oriented senders should terminate each message with a newline.
- Confirm the test event is indexed in Elasticsearch.
$ curl -s 'http://elasticsearch.example.net:9200/tcp-events-*/_search?q=message:"tcp%20input%20test"&size=1&pretty' { "took" : 76, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 16.404364, "hits" : [ { "_index" : "tcp-events-2026.01.07", "_id" : "5NVHmJsBMfcBipKWCNXA", "_score" : 16.404364, "_source" : { "ingest_source" : "beats", "@version" : "1", "@timestamp" : "2026-01-07T11:45:50.610759792Z", "message" : "tcp input test", "level" : "info", "app" : "demo", "tags" : [ "tcp" ] } } ] } }If the pipeline uses a different output, use that output’s confirmation path (file written, message delivered, document present) instead of querying Elasticsearch.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
