Depois de configurar o ELK com sucesso com entradas de arquivo, encaminhador de logstash e ver os logs no fluxo do Kibana de alguns servidores, tentei configurar uma entrada TCP:
tcp {
codec => "json"
host => "localhost"
port => 9250
tags => ["sensu"]
}
O remetente é sensu e as mensagens estão de fato em JSON - verifiquei isso com o comando tcpdump.
O log do Logstash indica que as conexões são aceitas:
{: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"}
No entanto, os dados parecem não ir mais longe e não podem ser encontrados em Kibana.
Cheguei ao ponto de desabilitar as outras entradas e observei o shard no elasticsearch (curl 'localhost:9200/_cat/shards'), que não aumentou de tamanho.
De acordo comesse linkEstou no caminho certo, mas provavelmente só estou fazendo algo bobo em algum lugar... Agradecemos antecipadamente.
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
Responder1
Depois de mais alguns dias frustrantes, concluí que o codec json/json_lines está quebrado - possivelmente apenas quando usado com entradas tcp.
No entanto, encontrei uma solução alternativa, usando um filtro:
filter {
if ("sensu" in [tags]) {
json {
"source" => "message"
}
}
}
Isso e algumas mutações produzem o efeito que eu estava tentando alcançar originalmente. Para a posteridade, aqui está meu logstash.conf de trabalho que combina logs e dados de métricas de CPU/memória do sensu:
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"
}
}
Não relacionado ao problema: a "saída" é recebida como vários valores separados por espaços, daí a operação "dividir". O segundo elemento é usado e depois convertido para float, para que o Kibana represente-o bem (algo que aprendi da maneira mais difícil).