Logstash TCP-Eingabe nicht an Elasticsearch weitergegeben

Logstash TCP-Eingabe nicht an Elasticsearch weitergegeben

Nachdem ich ELK erfolgreich mit Dateieingaben und Logstash-Forwarder eingerichtet hatte und Protokolle von einigen Servern im Kibana-Fluss sah, habe ich versucht, eine TCP-Eingabe einzurichten:

tcp {
    codec => "json"
    host => "localhost"
    port => 9250
    tags => ["sensu"]
  }

Der Absender ist sensu und die Nachrichten sind tatsächlich in JSON – dies wurde mit dem Befehl tcpdump überprüft.

Das Logstash-Protokoll zeigt an, dass die Verbindungen akzeptiert werden:

{:timestamp=>"2015-06-15T14:03:39.832000+1000", :message=>"Accepted connection", :client=>"127.0.0.1:38065", :server=>"localhost:9250", :level=>:debug, :file=>"logstash/inputs/tcp.rb", :line=>"146", :method=>"client_thread"}
{:timestamp=>"2015-06-15T14:03:39.962000+1000", :message=>"config LogStash::Codecs::JSONLines/@charset = \"UTF-8\"", :level=>:debug, :file=>"logstash/config/mixin.rb", :line=>"112", :method=>"config_init"}
{:timestamp=>"2015-06-15T14:03:39.963000+1000", :message=>"config LogStash::Codecs::Line/@charset = \"UTF-8\"", :level=>:debug, :file=>"logstash/config/mixin.rb", :line=>"112", :method=>"config_init"}

Die Daten scheinen jedoch nicht weiterzureichen und können in Kibana nicht gefunden werden.

Ich ging so weit, die anderen Eingaben zu deaktivieren, und beobachtete dann den Shard in Elasticsearch (curl 'localhost:9200/_cat/shards'), dessen Größe nicht zunahm.

Entsprechenddieser LinkIch bin auf dem richtigen Weg, mache aber wahrscheinlich nur irgendwo etwas Dummes ... Vielen Dank im Voraus.

logstash.conf:

input {
  file {
    path => ["/var/log/messages", "/var/log/secure", "/var/log/iptables"]
    type => "syslog"
    start_position => "end"
  }

  lumberjack {
    port => 5043
    type => "logs"
    ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"
    ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"
  }

  tcp {
    codec => "json"
    host => "localhost"
    port => 9250
    tags => ["sensu"]
  }

}

output {
  elasticsearch {
    host => "localhost"
    cluster => "webCluster"
  }
}

elasticsearch.yml:

cluster.name: webCluster
node.name: "bossNode"
node.master: true
node.data: true
index.number_of_shards: 1
index.number_of_replicas: 0
network.host: localhost

Antwort1

Nach einigen weiteren frustrierenden Tagen bin ich zu dem Schluss gekommen, dass der JSON/JSON_LINES-Codec defekt ist – möglicherweise nur bei Verwendung mit TCP-Eingaben.

Ich habe jedoch mithilfe eines Filters eine Problemumgehung gefunden:

filter {
  if ("sensu" in [tags]) {
    json {
      "source" => "message"
    }
  }
}

Dies und einige Mutationen erzeugen den Effekt, den ich ursprünglich erreichen wollte. Für die Nachwelt ist hier meine funktionierende logstash.conf, die Protokolle und CPU-/Speichermetrikdaten von sensu kombiniert:

input {
  file {
    path => [
      "/var/log/messages"
      , "/var/log/secure"
    ]
    type => "syslog"
    start_position => "end"
  }

  file {
    path => "/var/log/iptables"
    type => "iptables"
    start_position => "end"
  }

  file {
    path => ["/var/log/httpd/access_log"
        ,"/var/log/httpd/ssl_access_log"
    ]
    type => "apache_access"
    start_position => "end"
  }

  file {
    path => [
      "/var/log/httpd/error_log"
      , "/var/log/httpd/ssl_error_log"
    ]
    type => "apache_error"
    start_position => "end"
  }

  lumberjack {
    port => 5043
    type => "logs"
    ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"
    ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"
  }

  tcp {
    host => "localhost"
    port => 9250
    mode => "server"
    tags => ["sensu"]
  }

}

filter {
  if ("sensu" in [tags]) {
    json {
      "source" => "message"
    }
    mutate {
      rename => { "[check][name]" => "type" }
      replace => { "host" => "%{[client][address]}" }
      split => { "[check][output]" => " " }
      add_field => { "output" => "%{[check][output][1]}" }
      remove_field => [ "[client]", "[check]", "occurrences" ]
    }
  } else if([type] == "apache_access") {
    grok {
      match => { "message" => "%{IP:client}" }
    }
  }
}

filter {
  mutate {
    convert => { "output" => "float" }
  }
}

output {
  elasticsearch {
    host => "localhost"
    cluster => "webCluser"
  }
}

Unabhängig vom Problem: Die „Ausgabe“ wird als mehrere durch Leerzeichen getrennte Werte empfangen, daher die „Split“-Operation. Das zweite Element wird verwendet und dann in Float umgewandelt, damit Kibana es schön grafisch darstellen kann (etwas, das ich auf die harte Tour gelernt habe).

verwandte Informationen