tail
James Fuller, DevOps for Web Express
Office of Strategic Relations
Follow along at: http://rawgit.com/jwfuller/elk_tech_talk/master/index.html#/
When something goes wrong, you need grep
, awk
, |
and RegEx black magic to find what you are looking for
grep "Invalid user" /var/log/httpd/auth.log | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | uniq
http://www.lalocadelosgatos.com/wp-content/uploads/2012/10/gato-disfraz-ciervo.jpeg
Lightweight shippers written in Golang that send data from edge machines to Logstash and Elasticsearch.
You don't have to use a broker, but there are some benefits
Redis is commonly used as a broker.
Beats now fufills this need to some degree.
Logstash has three basic parts
Types include:
input {
beats {
port => 5044
ssl_certificate => "/usr/local/openssl/certs/crt/beat-selfsigned.crt"
ssl_key => "/usr/local/openssl/certs/key/beat.key"
}
file {
type => "mysql-slow"
path => "/var/log/mysql/mysql-slow.log"
codec => multiline {
pattern => "^# User@Host:"
negate => true
what => previous
}
}
}
filter {
if [type] == "varnishncsa" {
grok {
match => { "message" => '%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:varnish_timestamp}\] \"%{WORD:verb} %{NOTSPACE:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:response} %{NOTSPACE:bytes} %{QS:referrer} %{QS:agent} %{QS:varnish_response} %{QS:varnish_backend} %{QS:varnish_f5_destination}' }
}
mutate {
convert => [ "bytes", "integer" ]
add_field => { "signal" => "signal" }
}
if [bytes] == "-" {
mutate {
replace => { "bytes" => 0 }
}
}
date {
locale => "en"
match =>["varnish_timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
target => ["@timestamp"]
add_tag => [ "tmatch" ]
}
}
}
From the logstash docs:
Grok is currently the best way in logstash to parse crappy unstructured log data into something structured and queryable.
Grok pattern include:
filter {
if [type] == "access" {
grok {
match => {
"message" => '%{IPORHOST:first_ip}? %{COMBINEDAPACHELOG}'
}
}
date {
locale => "en"
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
timezone => "America/Denver"
target => ["@timestamp"]
add_tag => [ "tmatch" ]
}
mutate {
rename => [ "clientip", "varnish_ip"]
rename => [ "first_ip", "client_ip"]
convert => [ "bytes", "integer" ]
}
geoip {
source => "client_ip"
}
}
}
output {
if [type] == 'drupal_syslog' {
elasticsearch {
index => "logstash-drupal_syslog-%{+YYYY.MM.dd}"
host => "welastic.colorado.edu"
}
} else if [mysql] == "mysql" {
elasticsearch {
index => "logstash-mysql-%{+YYYY.MM.dd}"
host => "welastic.colorado.edu"
}
} else if [varnishncsa] == "varnishncsa" {
elasticsearch {
index => "logstash-varnishncsa-%{+YYYY.MM.dd}"
host => "welastic.colorado.edu"
}
} else {
elasticsearch {
host => "welastic.colorado.edu"
}
}
}
I could use some post-launch support and help for {URL}
At times, including right now, the home page displays the words "Information for People" instead of the correct home page. I thought I had made it go away myself just before launch, but clearly not.
It may have started when a few weeks ago when I renamed the page that is now "Overview" to "Home."
Thanks for your help.
Pat
A few weeks? Lets grab 30 days of logs
163 million events
Limit search to Production and our Application log
Down to 10 million events
Limit further to the specific instance and for 'Interference'
Down to 309 events
Limit further to 'content update' events
14 events
User and another person got into an edit war
Nope, increase in 'signal' logging
curl 'localhost:9200/_cat/health?v'
epoch timestamp cluster status node.total node.data shards pri relo init unassign
1394735289 14:28:09 elasticsearch yellow 1 1 5 5 0 0 5
curl 'localhost:9200/_cat/indices?v'
health status index pri rep docs.count docs.deleted store.size pri.store.size
green open varnish 5 0 11434 0 64mb 32mb
green open access 5 0 2030 0 5.8mb 5.8mb
green open mysql 5 0 1054 0 8 8mb 45mb
green open drupal 5 0 12030 0 1.2G 1.2G
filter {
if [type] == "drupal_syslog" {
grok {
match => {
"message" =>
'%{SYSLOGBASE} %{URI:drupal_base_url}\|%{INT:drupal_unix_timestamp}\|%{DATA:drupal_category}\|%{IP:ip}\|%{URI:drupal_request_url}\|(?:%{URI:drupal_referrer}|)\|%{INT:drupal_uid}\|(?:%{URI:drupal_link}|)\|%{GREEDYDATA:drupal_message}' }
}
mutate {
gsub => [ "drupal_category", "\s", "_"]
add_field => { "signal" => "signal" }
}
}
}
filter {
if [type] == "mysql" {
grok {
match => [
"message",
"^# User@Host: %{USER:user}(?:\[[^\]]+\])?\s+@\s+%{HOST:host}?\s+\[%{IP:ip}?\]"
]
}
grok {
match => [
"message",
"^# Query_time: %{NUMBER:duration:float}\s+Lock_time: %{NUMBER:lock_wait:float} Rows_sent: %{NUMBER:results:int} \s*Rows_examined: %{NUMBER:scanned:int}"
]
}
grok {
match => [
"message",
"^SET timestamp=%{NUMBER:timestamp};"
]
}
date {
match => [ "timestamp", "UNIX" ]
}
}
}