How to configure a Logstash file input

A Logstash file input watches an existing log file or file pattern and turns each new line into a pipeline event. Operators use it when an application writes plain text logs locally and Logstash is responsible for sending those lines to Elasticsearch or another output.

The file input tracks byte offsets in a sincedb file so restarts can resume from the last consumed position. Tail mode follows files that keep growing, while read mode is for content-complete files, so a continuously written application log should normally use an absolute path, explicit tail mode, and a dedicated sincedb_path.

The pipeline needs a readable source file, a validated configuration, and a real event test after the service restarts. start_position ⇒ “beginning” affects only files that do not already have sincedb state, and remote network filesystems can produce misleading file identity or offset behavior.

Steps to configure a file input in Logstash:

  1. List the log files matched by the planned absolute path pattern.
    $ sudo ls /var/log/app/*.log
    /var/log/app/app-error.log
    /var/log/app/app.log

    Logstash file input paths must be absolute. Keep rotated compressed files out of the match with exclude unless the pipeline is intentionally reading archive files in read mode.

  2. Confirm the logstash service account can read one matched file.
    $ sudo -u logstash test -r /var/log/app/app.log

    No output means the read check passed. If the command exits with an error, fix the file mode, file group, or parent-directory execute permission before editing the pipeline.

  3. Open the file input pipeline configuration.
    $ sudoedit /etc/logstash/conf.d/40-file-input.conf

    Package installs normally load files under /etc/logstash/conf.d/ through /etc/logstash/pipelines.yml. Use the active path.config value on hosts with custom pipeline manifests.

  4. Add the file input and destination output.
    input {
      file {
        id => "app_file_input"
        path => ["/var/log/app/*.log"]
        exclude => ["*.gz"]
        mode => "tail"
        start_position => "beginning"
        sincedb_path => "/var/lib/logstash/file-input-app.sincedb"
      }
    }
    
    output {
      elasticsearch {
        hosts => ["http://elasticsearch.example.net:9200"]
        data_stream => false
        ilm_enabled => false
        index => "app-logs-%{+YYYY.MM.dd}"
      }
    }

    Use a different sincedb_path for each file input. Reusing the same file lets inputs overwrite each other's offsets, and deleting it can replay old lines into the output.

    The elasticsearch output block is a minimal index-mode destination for the smoke test. Use the dedicated output guide when the cluster requires HTTPS, authentication, custom certificates, ILM, or data streams.
    Related: How to configure Logstash output to Elasticsearch

  5. Test the pipeline configuration with the packaged settings directory and a temporary data path.
    $ sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash --path.data /tmp/logstash-file-input-test --config.test_and_exit -f /etc/logstash/conf.d/40-file-input.conf
    Using bundled JDK: /usr/share/logstash/jdk
    ##### snipped #####
    Configuration OK
    [2026-06-18T15:17:02,718][INFO ][logstash.runner          ] Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash

    The temporary --path.data directory keeps the one-off validation away from /var/lib/logstash. Current package installs should run this check as the logstash service account unless allow_superuser was intentionally enabled.

  6. Remove the temporary validation data path.
    $ sudo rm --recursive --force /tmp/logstash-file-input-test
  7. Restart the Logstash service to load the file input.
    $ sudo systemctl restart logstash.service

    Restarting Logstash pauses every active pipeline while inputs, filters, and outputs reopen.

  8. Check the Logstash service state after the restart.
    $ sudo systemctl status logstash.service --no-pager --lines=0
    ● logstash.service - logstash
         Loaded: loaded (/usr/lib/systemd/system/logstash.service; enabled; preset: enabled)
         Active: active (running) since Thu 2026-06-18 15:24:41 UTC; 7s ago
       Main PID: 24817 (java)
          Tasks: 96 (limit: 28486)
         Memory: 1.0G
  9. Append a unique test line to a watched file.
    $ printf '2026-06-18T15:25:00Z INFO request_id=9b2a5f2c status=200 path=/health logstash-file-input-test\n' | sudo tee -a /var/log/app/app.log
    2026-06-18T15:25:00Z INFO request_id=9b2a5f2c status=200 path=/health logstash-file-input-test

    Because the input runs in tail mode, append the smoke-test line after Logstash is running so it is treated as new data even when older sincedb state exists.

  10. Verify the sincedb file exists after the input consumes the line.
    $ sudo ls -l /var/lib/logstash/file-input-app.sincedb
    -rw------- 1 logstash logstash 105 Jun 18 15:25 /var/lib/logstash/file-input-app.sincedb

    The timestamp should change after new lines are consumed. A missing file usually means the watched path did not match, Logstash could not read the file, or the pipeline did not start.

  11. Search the destination index for the smoke-test event.
    $ curl --silent --show-error --fail "http://elasticsearch.example.net:9200/app-logs-*/_count?q=logstash-file-input-test&pretty"
    {
      "count" : 1,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      }
    }

    A count of 1 or more confirms that the file input read the appended line and the output wrote it to the expected index pattern. If the count stays at 0, check /var/log/logstash/logstash-plain.log for file permission, sincedb, and output connection errors.