Peter Roßbach Systemarchitekt Logging Best Practice formulieren, ausgeben und analysieren
Logging Best Practice formulieren, ausgeben und analysieren Peter Roßbach 1 Peter Roßbach Gründer der bee42 solutions gmbh Neartime Application Monitoring DevOps, JavaScript, HTML 5, nosql, Virtual Appliance IT-Systemarchitekt, Berater, Trainer Entwickler im Apache Tomcat Projekt Mitglied der Apache Software Foundation Fachautor und Speaker auf deutschen Java Konferenzen 2
Schmerzlich erlebt vom Administrator Unterschätzt von uns Entwicklern Oft formuliert für den falsche Zweck oder es konnte schlicht kein realer Nutzer identifiziert werden Willkommen im Land der Möglichkeiten 3 Meine Erlebniswelt Logging 4
Es fehlt an Regeln für das produzieren von Log-Ausgaben 5 Verwendet einen aktuellen Log-Framework 6
Slf4j enthältet Möglichkeiten zur Umlenkung aller Ausgaben von JUL,JCL,log4j auf logback! 7 Sprache Formuliere der Ausgaben in englischer Sprache Setzen der Default-Language Je nach Transport muss es Ascii sein Besser ist die Verwendung von UTF-8 8
Nutzt ein einheitliches Standardformat für die Log-Ausgabe und produziere Log-Events Syslog GraylogEventLogFormat logstash Splunk loggly 9 Nah so was... 2013-04-23T09:44:55.000746+0200 INFO {AliveCheckThread [org.apache.http.impl.client.defaulthttpclient] : [I/O exception (org.apache.http.nohttpresponseexception) caught when processing request: The target server failed to respond] ::1 - - [20/Apr/2013:17:42:56 +0200] "GET /ctc-todo-service HTTP/1.1" 200 105 10
MultiLine 2013-04-23T09:44:30.000715+0200 ERROR {Grizzly-IdleTimeoutFilter-IdleCheck xxxx.servlet.heartbeatmessageinboundproxy] : [accesswithwebsocket -> onerror:] java.util.concurrent.timeoutexception: Timeout exceeded! at com.ning.http.client.providers.grizzly.grizzlyasynchttpprovider.timeout(grizzlyasynchttpprovi der.java:518) [async-http-client-1.7.7.jar:na]! at com.ning.http.client.providers.grizzly.grizzlyasynchttpprovider $3.onTimeout(GrizzlyAsyncHttpProvider.java:350) [async-http-client-1.7.7.jar:na]! at org.glassfish.grizzly.utils.idletimeoutfilter $DefaultWorker.doWork(IdleTimeoutFilter.java:385) [grizzly-framework-2.2.10.jar:2.2.10]! at org.glassfish.grizzly.utils.idletimeoutfilter $DefaultWorker.doWork(IdleTimeoutFilter.java:365) [grizzly-framework-2.2.10.jar:2.2.10]! at org.glassfish.grizzly.utils.delayedexecutor$delayedrunnable.run(delayedexecutor.java: 149) [grizzly-framework-2.2.10.jar:2.2.10]! at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1110) [na: 1.7.0_09]! at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:603) [na: 1.7.0_09]! at java.lang.thread.run(thread.java:722) [na:1.7.0_09] 11 Log Event vs. Log Ausgabe Zeitpunkt Kontext Informationen als machinenverarbeitbares Format 12
Was geht... {! "@source":"file://127.0.0.1:6880/access_log",! "@source_host": "127.0.0.1",! "@source_path": "access_log",! "@tags":["proxy","httpd", "httpd6080"],! "@message": "::1 - - [20/Apr/2013:17:42:56 +0200] \"GET /ctc-todo-service/rest/todo HTTP/1.1\" 200 105",! "@fields": {!! "timestamp": "2013-04-20T17:42:56.106+0200",!! "clientip": "::1",!! "duration": 3484,!! "status": 200,!! "request": "/ctc-todo-service/rest/todo",!! "urlpath": "/ctc-todo-service/rest/todo",!! "urlquery": "",!! "method": "GET",!! "bytes": 105!! "referer": \"http://localhost:6880/ctc-todo-angularjs/\",!! "useragent": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.28.10 (KHTML, like Gecko) Version/6.0.3 Safari/536.28.10\"!! "requestid": \"httpd6880.uxlbvn8aaaeaasgkctiaaaba\" 13 machine readable log.info( user {, bill {, pay {, userid, billid, betrag); noch ein einfacher Matcher: /user (\d+), bill (\d+), pay (\d+)$/ Text und Information trennen und die Ausgabe vielleicht lieber als JSON Datensatz ausgeben: User pay the bill { "user": 122121, "bill": 12312312, "betrag": 1212.12 14
Verwende die Log-Level konsequent! 15 TRACE Code Trace DEBUG Informationen zur Problemanalyse INFO Start/Stop von Komponenten und Abläufen WARN Funktionalitäten ist beeinträchtigt ERROR Dringender Handlungsbedarf 16
Nutze die Log-Kategorien Einhalten von Hierarchien Auswahl der Aussteuerung Beachte den Modulschnitt Anderer Zweck == andere Kategorie 17 Architektur Log-Category Jersey com.sun.jersey Module Modul 2 Module 3 org.module1 org.module2 org.module3 Spring org.springframework Hibernate org.hibernate 18
Bilde einen LOG-Context Login/SessionID FlowID Request ID Thread ID PID ServiceID Transaction ID Host 19 Zeitstempel... 1304060505 22/Apr/2013:07:05:26 +0000 Thu,22 Apr 2013 01:05:25-0600 Apr 22 20:21:47 030813 13:21:24 110429.071055,118 @60000000037c219bf2ef02e98 20
Einheitliches Format (ISO8601) yyyy-mm-dd't'hh:mm:ss.sssz => 2013-04-22T06:05:56.264+0200 Synchronität zwischen den Systemen gewährleisten (NTP) 21 Formuliere die Ausgaben für einen realen Anwendungsfall! 22
Gibt es eine klare Anforderung für den Zweck der Ausgabe! Journal Debugging Metriken Profiling Fehleranzeige 23 Tools für die Auswertung und Analyse nutzen! 24
Experimente httpd udp Tomcat App syslog access_log GELF logstash shipper statd redis logstash indexer graphite / CtC Monitoring elasticsearch kibana 25 LogStash LogStash 33 17 46 log output inputs filter outputs info Watchdog Config 26
inputs amqp drupal_dblog elasticsearch eventlog exec file ganglia gelf gemfire generator graphite heroku imap irc log4j lumberjack lumberjack2 pipe rabbitmq redis relp snmptrap sqs stdin stomp syslog tcp twitter udp varnishlog websocket xmpp zenoss zeromq 27 Filters alter anonymize checksum clone csv date dns environment gelfify geoip grep grok grokdiscovery json kv metrics multiline mutate noop ruby sleep split syslog_pri translate urldecode useragent xml zeromq 28
outputs amqp boundary circonus cloudwatch datadog elasticsearch elasticsearch_http elasticsearch_river email exec file ganglia gelf gemfire graphite graphtastic hipchat http internal irc juggernaut librato loggly lumberjack metriccatcher mongodb nagios nagios_nsca null opentsdb pagerduty pipe rabbitmq redis riak riemann sns sqs statsd stdout stomp syslog tcp websocket xmpp zabbix zeromq 29 Information Extraktion grok {! type => "tomcat-access-log"! patterns_dir => "patterns"! pattern => '%{IPORHOST:clientip %{USER:ident % {USER:auth \"%{TIMESTAMP_ISO8601:timestamp\" \"% {WORD:verb %{URIPATHPARAM:request HTTP/% {NUMBER:httpversion\" %{NUMBER:response:int (?:% {NUMBER:bytes:int -) \"(?:%{URI:referrer -)\" (?:% {QS:agent -) %{NUMBER:duration:int (?:%{WORD:session_id. %{WORD:node -) \"(?:%{GREEDYDATA:requestid -)\"' 30
31 32
shipper (input) input {! gelf {!! type => "gelf"!! file { path => '/Users/peter/develop/advancedlogging/instance/node60/logs/access.log' format => 'plain' type => 'tomcat-access-log' tags => 'node60' udp {!port => 57080!type => "apache_httpd"!buffer_size => 8192!format => "json_event" 33 shipper (filter) filter { grok {! type => "tomcat-access-log"! patterns_dir => "/Users/peter/develop/advancedlogging/server/stash/patterns"! pattern => '%{IPORHOST:clientip %{USER:ident %{USER:auth \"% {TIMESTAMP_ISO8601:timestamp\" \"%{WORD:verb %{URIPATHPARAM:request HTTP/% {NUMBER:httpversion\" %{NUMBER:response:int (?:%{NUMBER:bytes:int -) \"(?:%{URI:referrer -)\" (?:% {QS:agent -) %{NUMBER:duration:int (?:%{WORD:session_id.%{WORD:node -) \"(?:% {GREEDYDATA:requestid -)\"' date { type => "apache_httpd" match => [ "timestamp", "ISO8601" ] mutate { type => "apache_httpd" remove => [ "timestamp" ] 34
shipper (output) output { stdout {!debug => true!debug_format => "json" redis { host => "127.0.0.1" data_type => "list" key => "logstash" statsd {!! type => "apache_httpd"!! increment => "apache.status.%{status"!! count => ["apache.bytes", "%{bytes"] 35 indexer (input/output) input { redis { host => "127.0.0.1" type => "redis-input" data_type => "list" key => "logstash" format => "json_event" output { elasticsearch {!embedded => true #host => "127.0.0.1"!! #cluster => "stash"! #port => "9300" #index => "logstash-%{+yyyy.mm.dd" #type => "raw_public_log" 36
37 38
39 40
41 42
Anforderung an die Ausgaben klären Logging als Backend, wie eine Datenbank begreifen Vereinbare ein Review und Test der Log-Ausgaben! Validieren der eigenen Ausgaben! 43 Klare Regeln Behandelt Logausgaben wie Datenbank-Operationen Definiere den Zweck Verwende nur Ausgaben die auch ausgewertet werden. 44
Wer ist der Konsument? Operator Developer Produkt Owner Security Officer 45 Die Balance gelingt nur mit Übung... 46
Kommt zu den Workshop in diesem Jahr oder vereinbart eine persönliche Termin!! WJAX München 2013 Apache Tomcat 8 AngularJS Monitoring & Websockets Loganalyse OOP München 2014 CtC goes Live... http://www.bee42.com bee42 suchen Dich... https://github.com/atmosphere/atmosphere Entwickler (JavaScript, node.js, MongoDB, Redis, Java, Ruby, Tomcat) Administrator (Vagrant, Puppet, Mcollective, Jenkins, Linux OS) jobs-2012@bee42.com +49-157-72549263 47