SlideShare uma empresa Scribd logo
1 de 28
Baixar para ler offline
JAVA logging a confronto
         Paolo Predonzani
paolo.predonzani@manydesigns.com

   JUG Genova – 9 Marzo 2011
Logging... alla fine delle fini
Si tratta di sostituire questo:

System.out.println(“La variabile x vale: ” + x);
System.err.println(“Accesso negato: ” + filename);


...con questo:

Logger logger = LoggerFactory.getLogger(“mylogger”);
logger.debug(“La variabile x vale: ” + x);
logger.error(“Accesso negato: ” + filename);
Perché System.out e System.err
         non sono sufficienti?
●   Solo due stream non bastano per:
    ●   Messaggi UI a carattere
    ●   Messaggi tecnici sul funzionamento interno
    ●   Traccia di sicurezza
    ●   Altri...
Spesso si vogliono attivare/disattivare i messaggi
tecnici in maniera selettiva a seconda della
situazione. Esempio: i messaggi richiesti in
sviluppo possono essere molto diversi da quelli
richiesti in esercizio.
Il messaggio comunque è...
    Fate logging (e non fate debugging)
“As personal choice, we tend not to use debuggers beyond getting a
 stack trace or the value of a variable or two. One reason is that it
 is easy to get lost in details of complicated data structures and
 control flow; we find stepping through a program less productive
 than thinking harder and adding output statements and self-checking
 code at critical places. Clicking over statements takes longer than
 scanning the output of judiciously-placed displays. It takes less
 time to decide where to put print statements than to single-step to
 the critical section of code, even assuming we know where that
 is. More important, debugging statements stay with the program;
 debugging sessions are transient.”
                                         Brian W. Kernighan and Rob Pike
Output o così:
Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener
createDatabaseAbstraction

INFO: Database product name: PostgreSQL

Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener
createDatabaseAbstraction

INFO: Database product version: 8.3.5

Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener
createDatabaseAbstraction

INFO: Database major/minor version: 8.3

Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener
createDatabaseAbstraction

INFO: Driver name: PostgreSQL Native Driver


O così:
Logger (categorie di logging)
Un “logger” rappresenta una categoria di messaggi
collegati, da controllare in modo unificato.
Logger logger = LoggerFactory.getLogger(“security”);

Più spesso è semplicemente la categoria dei messaggi
prodotti da una certa classe:
Logger logger =
LoggerFactory.getLogger(“com.example.MyClass”);

O più semplicemente:
Logger logger =
LoggerFactory.getLogger(com.example.MyClass.class);

I logger formano una gerarchia: il carattere “.”
separa i padri/figli.
Livelli di logging
I livelli di logging indicano la gravità o importanza del
messaggio, es: trace, debug, info, warn, error.
logger.setLevel(Level.INFO);
logger.info(“Avvio programma”); // sarà stampato
int x = 2;
logger.debug(“x vale ” + x); // NON sarà stampato



I livelli di logging per ogni logger sono configurabili
programmaticamente (come in esempio) o più
frequentemente tramite file di configurazione .properties
o .xml
Esempio di configurazione xml
<configuration>
...


      <logger name="com.example" level="info"/>
      <logger name="com.example.MyClass" level="debug"/>


      <logger name="org.hibernate" level="warn"/>


      <root level="info">
          <appender-ref ref="STDOUT"/>
      </root>
</configuration>
Handler e formatter
●   Uno Handler è un oggetto che si occupa della
    scrittura fisica dei log su un file, su db, su
    server di eventi, ecc.
    ●   P.e.: un handler per i messaggi normali e uno per i
        messaggi di sicurezza
    ●   Più logger insististono su un handler
●   Un Formatter è un oggetto che formatta in testo
    una chiamata di logging e i suoi parametri
%d{HH:mm:ss.SSS} [userId=%X{userId},userName=%X{userName}]
%logger{40} [%F:%L]%n%level: %msg%n
13:09:49.026 [userId=1001,userName=predo]
c.m.p.database.JdbcConnectionProvider [ConnectionProvider.java:222]
WARN: Could not create database abstraction
Mapped Diagnostic Context
●   Una mappa chiave-valore utile a identificare il
    contesto di esecuzione, p.e.: l'utente, il client,
    ecc.
Nested Diagnostic Context
●   Uno stack per identificare il con contesto di esecuzione
●   Permette di dire “siamo dentro all'applicativo X, modulo Y,
    sottomodulo Z. Oppure di esprime contesti di algoritmi
    ricorsivi.
Logging - il rovescio della medaglia:
    proliferazione delle librerie

Perché tante librerie di logging?
●   Java logging rilasciato tardi (JDK 1.4)
●   Funzionalità distintive delle singole librerie
Problematiche:
●   Più API da imparare
●   Versioni diverse della stessa libreria
●   Conflitti di classloading in ambienti server
Bisogna distinguere
●   Implementazioni di base:
    ●   Java logging (java.util.logging)
    ●   Log4J
    ●   Logback
●   API di astrazione:
    ●   Apache commons logging
    ●   SLF4J
Perché astrarre?
●   Per cambiare l'implementazione sottostante
●   Per configurare in un solo punto
●   Per formattare in modo omogeneo
Astrazione, implementazione
 e bridging
                                                  Altra API o
                                                  framework



                                                    bridge
                         API
                    di astrazione




Adapter per         Adapter per     Adapter per
Java logging           log4j          logback




Java logging            log4j         logback
Java logging – configurazione




handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level = ALL

java.util.logging.ConsoleHandler.level = INFO
java.util.logging.FileHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Log4J esempio di configurazione
              tramite propeties
log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout



# Pattern to output the caller's file name and line number.

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n



log4j.appender.R=org.apache.log4j.RollingFileAppender

log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB

# Keep one backup file

log4j.appender.R.MaxBackupIndex=1



log4j.appender.R.layout=org.apache.log4j.PatternLayout

log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
Logback – configurazione xml


<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
           <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg
%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
Logback – configurazione groovy



import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import static ch.qos.logback.classic.Level.DEBUG
appender("STDOUT", ConsoleAppender) {
  encoder(PatternLayoutEncoder) {
    pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
  }
}
root(DEBUG, ["STDOUT"])
Logback – esempio di output
13:09:49.026 [userId=,userName=] c.m.p.database.JdbcConnectionProvider [ConnectionProvider.java:222]
WARN: Could not create database abstraction for portofino
org.postgresql.util.PSQLException: Connection refused. Check that the hostname and port are correct and that the
postmaster is accepting TCP/IP connections.
     at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:123) ~[postgresql-
8.3-606.jdbc3.jar:na]
     at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-8.3-
606.jdbc3.jar:na]
     at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:124) ~[postgresql-8.3-
606.jdbc3.jar:na]
     at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30) ~[postgresql-8.3-
606.jdbc3.jar:na]
     at org.postgresql.jdbc3.Jdbc3Connection.<init>(Jdbc3Connection.java:24) ~[postgresql-8.3-606.jdbc3.jar:na]
     at org.postgresql.Driver.makeConnection(Driver.java:386) ~[postgresql-8.3-606.jdbc3.jar:na]
     at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-8.3-606.jdbc3.jar:na]
     at java.sql.DriverManager.getConnection(DriverManager.java:525) ~[na:1.5.0]
     at java.sql.DriverManager.getConnection(DriverManager.java:171) ~[na:1.5.0]
     at com.manydesigns.portofino.database.JdbcConnectionProvider.acquireConnection(JdbcConnectionProvider.java:80)
~[JdbcConnectionProvider.class:na]
     at com.manydesigns.portofino.database.ConnectionProvider.init(ConnectionProvider.java:165)
~[ConnectionProvider.class:na]
     at
com.manydesigns.portofino.context.hibernate.HibernateContextImpl.loadConnections(HibernateContextImpl.java:137)
[HibernateContextImpl.class:na]
     at com.manydesigns.portofino.servlets.PortofinoListener.createContext(PortofinoListener.java:328)
[PortofinoListener.class:na]
     at com.manydesigns.portofino.servlets.PortofinoListener.contextInitialized(PortofinoListener.java:153)
[PortofinoListener.class:na]
     at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135) [catalina.jar:6.0.29]
     at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630) [catalina.jar:6.0.29]
     at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) [catalina.jar:6.0.29]
     at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) [catalina.jar:6.0.29]
Confronto implementazioni
                                  Java logging   Log4j               Logback
Licenza                           JDK            Apache              EPL/LGPL
Layout personalizzabili           estensione     sì                  sì
Numero di livelli                 7              6                   5
Configurazione                    properties     properties, xml,    xml, API,
                                                 API                 groovy
Configurazione per test o         no             no                  sì
condizionata
Reload configurazione             no             Sì tramite thread   sì senza thread
Diagnostic context                no             Nested/Mapped       Mapped
Jar/versione negli stacktrace     no             no                  sì
Diffusione                        scarsa         ampia               in crescita
Stabilità di API/configurazione   ferma          stabile             config cambiata
Documentazione                    buona          ottima              ottima
API                               minimale       buona               molto buona
Messaggi parametrizzati           no             tramite log4j-      sì
                                                 extras
Confronto API di astrazione

                               Commons logging   SLF4J

Licenza                        Apache            MIT

Numero di livelli              6                 6

Configurazione                 properties        -

Configurazione programmatica   no                no

Diffusione                     ampia             ampia

Bridging                       no                sì

Binding dell'implementazione   discovery         statica
Problematiche di logging su
              application server

●   Presenza/assenza delle librerie di logging
    nell'application server:
    ●   Presenza → conflitti con librerie in WEB-INF/lib
    ●   Assenza → assenza della funzionalità
●   Problemi di class loader
●   Memory-leak
Presenza delle librerie su vari
         appserver

            Java      log4j   logback   JCL   SLF4J
            logging


Tomcat 6    JULI

Jboss 5.1   Sì        Sì                Sì    Sì

Glassfish 3 Sì
Soluzioni
●   Usare una libreria di logging inusuale
    ●   Essendo improbabile che l'appserver la contenga,
        includerla nella webapp è sicuro
●   Usare Java logging standard
●   Includere la libreria nella webapp sempre
    ●   sperare che non vada in conflitto con l'appserver
    ●   va bene con API stabili
●   Includere o non includere la libreria nella
    webapp a seconda dell'appserver
Riferimenti
●   http://download.oracle.com/javase/1.4.2/docs/g
    uide/util/logging/overview.html
    http://commons.apache.org/logging/
●   http://logback.qos.ch/
●   http://logging.apache.org/log4j/
●   http://www.slf4j.org/
●   http://logging.apache.org/chainsaw/index.html
●   http://articles.qos.ch/thinkAgain.html

Mais conteúdo relacionado

Mais procurados

Async navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworkAsync navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworksparkfabrik
 
Node.js - Server Side Javascript
Node.js - Server Side JavascriptNode.js - Server Side Javascript
Node.js - Server Side JavascriptMatteo Napolitano
 
Webbit 2004: Tiger, java
Webbit 2004: Tiger, javaWebbit 2004: Tiger, java
Webbit 2004: Tiger, javaMatteo Baccan
 
Drupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupalDay
 
PHP Object Injection in Joomla...questo sconosciuto!
PHP Object Injection in Joomla...questo sconosciuto!PHP Object Injection in Joomla...questo sconosciuto!
PHP Object Injection in Joomla...questo sconosciuto!_EgiX
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsJUG Genova
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@UninaNaLUG
 
Php mysql e cms
Php mysql e cmsPhp mysql e cms
Php mysql e cmsorestJump
 
Smau milano 2012 massimiliano del cero
Smau milano 2012 massimiliano del ceroSmau milano 2012 massimiliano del cero
Smau milano 2012 massimiliano del ceroSMAU
 
breve introduzione a node.js
breve introduzione a node.jsbreve introduzione a node.js
breve introduzione a node.jseugenio pombi
 

Mais procurados (20)

Async navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworkAsync navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 framework
 
Node.js - Server Side Javascript
Node.js - Server Side JavascriptNode.js - Server Side Javascript
Node.js - Server Side Javascript
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
PHP Object Injection
PHP Object InjectionPHP Object Injection
PHP Object Injection
 
Corso Java 2 - AVANZATO
Corso Java 2 - AVANZATOCorso Java 2 - AVANZATO
Corso Java 2 - AVANZATO
 
Webbit 2004: Tiger, java
Webbit 2004: Tiger, javaWebbit 2004: Tiger, java
Webbit 2004: Tiger, java
 
Php mysql3
Php mysql3Php mysql3
Php mysql3
 
Drupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e DrupalDrupal Day 2011 - Node.js e Drupal
Drupal Day 2011 - Node.js e Drupal
 
EIP with Apache Camel
EIP with Apache CamelEIP with Apache Camel
EIP with Apache Camel
 
PHP Object Injection in Joomla...questo sconosciuto!
PHP Object Injection in Joomla...questo sconosciuto!PHP Object Injection in Joomla...questo sconosciuto!
PHP Object Injection in Joomla...questo sconosciuto!
 
Laravel 7 REST API
Laravel 7 REST APILaravel 7 REST API
Laravel 7 REST API
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMs
 
Design Pattern
Design PatternDesign Pattern
Design Pattern
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@Unina
 
Php mysql e cms
Php mysql e cmsPhp mysql e cms
Php mysql e cms
 
Ddive Xpage852
Ddive Xpage852Ddive Xpage852
Ddive Xpage852
 
Smau milano 2012 massimiliano del cero
Smau milano 2012 massimiliano del ceroSmau milano 2012 massimiliano del cero
Smau milano 2012 massimiliano del cero
 
Net core base
Net core baseNet core base
Net core base
 
Corso Java
Corso JavaCorso Java
Corso Java
 
breve introduzione a node.js
breve introduzione a node.jsbreve introduzione a node.js
breve introduzione a node.js
 

Destaque

DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011Fabrizio Giudici
 
Come Incorporare un Interprete Groovy in un Applicativo Java
Come Incorporare un Interprete Groovy in un Applicativo JavaCome Incorporare un Interprete Groovy in un Applicativo Java
Come Incorporare un Interprete Groovy in un Applicativo JavaPaolo Predonzani
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.comJUG Genova
 
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013Carlo Bonamico
 
ESP8266 and IOT
ESP8266 and IOTESP8266 and IOT
ESP8266 and IOTdega1999
 

Destaque (6)

DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011
 
JMeter
JMeterJMeter
JMeter
 
Come Incorporare un Interprete Groovy in un Applicativo Java
Come Incorporare un Interprete Groovy in un Applicativo JavaCome Incorporare un Interprete Groovy in un Applicativo Java
Come Incorporare un Interprete Groovy in un Applicativo Java
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.com
 
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013
AngularJS: How to code today with tomorrow tools - Codemotion Milan 2013
 
ESP8266 and IOT
ESP8266 and IOTESP8266 and IOT
ESP8266 and IOT
 

Semelhante a Logging

Netbeans e Xdebug per debugging e profiling di applicazioni PHP
Netbeans e Xdebug per debugging e profiling di applicazioni PHPNetbeans e Xdebug per debugging e profiling di applicazioni PHP
Netbeans e Xdebug per debugging e profiling di applicazioni PHPGiorgio Cefaro
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBStefano Dindo
 
April 2010 - Seam unifies JEE5
April 2010 - Seam unifies JEE5April 2010 - Seam unifies JEE5
April 2010 - Seam unifies JEE5JBug Italy
 
Seam unifies Java EE by Massimiliano Ciccazzo
Seam unifies Java EE by Massimiliano CiccazzoSeam unifies Java EE by Massimiliano Ciccazzo
Seam unifies Java EE by Massimiliano CiccazzoJava User Group Roma
 
Profilazione di applicazioni PHP con XHProf.
Profilazione di applicazioni PHP con XHProf.Profilazione di applicazioni PHP con XHProf.
Profilazione di applicazioni PHP con XHProf.Filippo Matteo Riggio
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5Matteo Baccan
 
Deployment ripetibili e automatizzati con Salt
Deployment ripetibili e automatizzati con SaltDeployment ripetibili e automatizzati con Salt
Deployment ripetibili e automatizzati con Saltitbabu
 
JAMP DAY 2010 - ROMA (1)
JAMP DAY 2010 - ROMA (1)JAMP DAY 2010 - ROMA (1)
JAMP DAY 2010 - ROMA (1)jampslide
 

Semelhante a Logging (20)

#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2
 
Linuxday2013
Linuxday2013 Linuxday2013
Linuxday2013
 
XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13
 
Netbeans e Xdebug per debugging e profiling di applicazioni PHP
Netbeans e Xdebug per debugging e profiling di applicazioni PHPNetbeans e Xdebug per debugging e profiling di applicazioni PHP
Netbeans e Xdebug per debugging e profiling di applicazioni PHP
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDB
 
Java Advanced
Java AdvancedJava Advanced
Java Advanced
 
April 2010 - Seam unifies JEE5
April 2010 - Seam unifies JEE5April 2010 - Seam unifies JEE5
April 2010 - Seam unifies JEE5
 
Seam unifies Java EE by Massimiliano Ciccazzo
Seam unifies Java EE by Massimiliano CiccazzoSeam unifies Java EE by Massimiliano Ciccazzo
Seam unifies Java EE by Massimiliano Ciccazzo
 
App Engine + Python
App Engine + PythonApp Engine + Python
App Engine + Python
 
pugBO #10 PSR e Composer
pugBO #10 PSR e ComposerpugBO #10 PSR e Composer
pugBO #10 PSR e Composer
 
DDive - 8.5.2 Xpages - L'evoluzione continua
DDive - 8.5.2 Xpages - L'evoluzione continuaDDive - 8.5.2 Xpages - L'evoluzione continua
DDive - 8.5.2 Xpages - L'evoluzione continua
 
TYPO3 CMS 8.1 - Le novità
TYPO3 CMS 8.1 - Le novitàTYPO3 CMS 8.1 - Le novità
TYPO3 CMS 8.1 - Le novità
 
DDive11 - xpages
DDive11 - xpagesDDive11 - xpages
DDive11 - xpages
 
3DD 1e Reconfig
3DD 1e Reconfig3DD 1e Reconfig
3DD 1e Reconfig
 
Profilazione di applicazioni PHP con XHProf.
Profilazione di applicazioni PHP con XHProf.Profilazione di applicazioni PHP con XHProf.
Profilazione di applicazioni PHP con XHProf.
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5
 
Deployment ripetibili e automatizzati con Salt
Deployment ripetibili e automatizzati con SaltDeployment ripetibili e automatizzati con Salt
Deployment ripetibili e automatizzati con Salt
 
Novità di Asp.Net 4.0
Novità di Asp.Net 4.0Novità di Asp.Net 4.0
Novità di Asp.Net 4.0
 
JAMP DAY 2010 - ROMA (1)
JAMP DAY 2010 - ROMA (1)JAMP DAY 2010 - ROMA (1)
JAMP DAY 2010 - ROMA (1)
 
Grasso Frameworks Ajax
Grasso Frameworks AjaxGrasso Frameworks Ajax
Grasso Frameworks Ajax
 

Mais de Paolo Predonzani

Wiki-like collaborative development for seamless customer involvement
Wiki-like collaborative development for seamless customer involvementWiki-like collaborative development for seamless customer involvement
Wiki-like collaborative development for seamless customer involvementPaolo Predonzani
 
How to put 100k lines of code into the (Google) cloud: storms and rainbows
How to put 100k lines of code into the (Google) cloud: storms and rainbowsHow to put 100k lines of code into the (Google) cloud: storms and rainbows
How to put 100k lines of code into the (Google) cloud: storms and rainbowsPaolo Predonzani
 
Portofino 4: Creare Webapp da Database Esistenti in 30 Secondi
Portofino 4: Creare Webapp da Database Esistenti in 30 SecondiPortofino 4: Creare Webapp da Database Esistenti in 30 Secondi
Portofino 4: Creare Webapp da Database Esistenti in 30 SecondiPaolo Predonzani
 
Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationPaolo Predonzani
 
Come Incorporare un Interprete Groovy in Java
Come Incorporare un Interprete Groovy in JavaCome Incorporare un Interprete Groovy in Java
Come Incorporare un Interprete Groovy in JavaPaolo Predonzani
 
70k linee di codice, tangle architetturali e le sfide del refactoring
70k linee di codice, tangle architetturali e le sfide del refactoring70k linee di codice, tangle architetturali e le sfide del refactoring
70k linee di codice, tangle architetturali e le sfide del refactoringPaolo Predonzani
 
Model Driven Engineering - ManyDesigns Portofino
Model Driven Engineering - ManyDesigns PortofinoModel Driven Engineering - ManyDesigns Portofino
Model Driven Engineering - ManyDesigns PortofinoPaolo Predonzani
 

Mais de Paolo Predonzani (7)

Wiki-like collaborative development for seamless customer involvement
Wiki-like collaborative development for seamless customer involvementWiki-like collaborative development for seamless customer involvement
Wiki-like collaborative development for seamless customer involvement
 
How to put 100k lines of code into the (Google) cloud: storms and rainbows
How to put 100k lines of code into the (Google) cloud: storms and rainbowsHow to put 100k lines of code into the (Google) cloud: storms and rainbows
How to put 100k lines of code into the (Google) cloud: storms and rainbows
 
Portofino 4: Creare Webapp da Database Esistenti in 30 Secondi
Portofino 4: Creare Webapp da Database Esistenti in 30 SecondiPortofino 4: Creare Webapp da Database Esistenti in 30 Secondi
Portofino 4: Creare Webapp da Database Esistenti in 30 Secondi
 
Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java Application
 
Come Incorporare un Interprete Groovy in Java
Come Incorporare un Interprete Groovy in JavaCome Incorporare un Interprete Groovy in Java
Come Incorporare un Interprete Groovy in Java
 
70k linee di codice, tangle architetturali e le sfide del refactoring
70k linee di codice, tangle architetturali e le sfide del refactoring70k linee di codice, tangle architetturali e le sfide del refactoring
70k linee di codice, tangle architetturali e le sfide del refactoring
 
Model Driven Engineering - ManyDesigns Portofino
Model Driven Engineering - ManyDesigns PortofinoModel Driven Engineering - ManyDesigns Portofino
Model Driven Engineering - ManyDesigns Portofino
 

Último

Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Associazione Digital Days
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Associazione Digital Days
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Associazione Digital Days
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Associazione Digital Days
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Associazione Digital Days
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Associazione Digital Days
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Associazione Digital Days
 
ScrapeGraphAI: a new way to scrape context with AI
ScrapeGraphAI: a new way to scrape context with AIScrapeGraphAI: a new way to scrape context with AI
ScrapeGraphAI: a new way to scrape context with AIinfogdgmi
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Associazione Digital Days
 

Último (9)

Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
 
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
 
ScrapeGraphAI: a new way to scrape context with AI
ScrapeGraphAI: a new way to scrape context with AIScrapeGraphAI: a new way to scrape context with AI
ScrapeGraphAI: a new way to scrape context with AI
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
 

Logging

  • 1. JAVA logging a confronto Paolo Predonzani paolo.predonzani@manydesigns.com JUG Genova – 9 Marzo 2011
  • 2. Logging... alla fine delle fini Si tratta di sostituire questo: System.out.println(“La variabile x vale: ” + x); System.err.println(“Accesso negato: ” + filename); ...con questo: Logger logger = LoggerFactory.getLogger(“mylogger”); logger.debug(“La variabile x vale: ” + x); logger.error(“Accesso negato: ” + filename);
  • 3. Perché System.out e System.err non sono sufficienti? ● Solo due stream non bastano per: ● Messaggi UI a carattere ● Messaggi tecnici sul funzionamento interno ● Traccia di sicurezza ● Altri... Spesso si vogliono attivare/disattivare i messaggi tecnici in maniera selettiva a seconda della situazione. Esempio: i messaggi richiesti in sviluppo possono essere molto diversi da quelli richiesti in esercizio.
  • 4. Il messaggio comunque è... Fate logging (e non fate debugging) “As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging statements stay with the program; debugging sessions are transient.” Brian W. Kernighan and Rob Pike
  • 5. Output o così: Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener createDatabaseAbstraction INFO: Database product name: PostgreSQL Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener createDatabaseAbstraction INFO: Database product version: 8.3.5 Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener createDatabaseAbstraction INFO: Database major/minor version: 8.3 Nov 11, 2009 11:40:06 AM com.manydesigns.portofino.methods.PortofinoServletContextListener createDatabaseAbstraction INFO: Driver name: PostgreSQL Native Driver O così:
  • 6. Logger (categorie di logging) Un “logger” rappresenta una categoria di messaggi collegati, da controllare in modo unificato. Logger logger = LoggerFactory.getLogger(“security”); Più spesso è semplicemente la categoria dei messaggi prodotti da una certa classe: Logger logger = LoggerFactory.getLogger(“com.example.MyClass”); O più semplicemente: Logger logger = LoggerFactory.getLogger(com.example.MyClass.class); I logger formano una gerarchia: il carattere “.” separa i padri/figli.
  • 7. Livelli di logging I livelli di logging indicano la gravità o importanza del messaggio, es: trace, debug, info, warn, error. logger.setLevel(Level.INFO); logger.info(“Avvio programma”); // sarà stampato int x = 2; logger.debug(“x vale ” + x); // NON sarà stampato I livelli di logging per ogni logger sono configurabili programmaticamente (come in esempio) o più frequentemente tramite file di configurazione .properties o .xml
  • 8. Esempio di configurazione xml <configuration> ... <logger name="com.example" level="info"/> <logger name="com.example.MyClass" level="debug"/> <logger name="org.hibernate" level="warn"/> <root level="info"> <appender-ref ref="STDOUT"/> </root> </configuration>
  • 9. Handler e formatter ● Uno Handler è un oggetto che si occupa della scrittura fisica dei log su un file, su db, su server di eventi, ecc. ● P.e.: un handler per i messaggi normali e uno per i messaggi di sicurezza ● Più logger insististono su un handler ● Un Formatter è un oggetto che formatta in testo una chiamata di logging e i suoi parametri %d{HH:mm:ss.SSS} [userId=%X{userId},userName=%X{userName}] %logger{40} [%F:%L]%n%level: %msg%n 13:09:49.026 [userId=1001,userName=predo] c.m.p.database.JdbcConnectionProvider [ConnectionProvider.java:222] WARN: Could not create database abstraction
  • 10. Mapped Diagnostic Context ● Una mappa chiave-valore utile a identificare il contesto di esecuzione, p.e.: l'utente, il client, ecc.
  • 11. Nested Diagnostic Context ● Uno stack per identificare il con contesto di esecuzione ● Permette di dire “siamo dentro all'applicativo X, modulo Y, sottomodulo Z. Oppure di esprime contesti di algoritmi ricorsivi.
  • 12. Logging - il rovescio della medaglia: proliferazione delle librerie Perché tante librerie di logging? ● Java logging rilasciato tardi (JDK 1.4) ● Funzionalità distintive delle singole librerie Problematiche: ● Più API da imparare ● Versioni diverse della stessa libreria ● Conflitti di classloading in ambienti server
  • 13. Bisogna distinguere ● Implementazioni di base: ● Java logging (java.util.logging) ● Log4J ● Logback ● API di astrazione: ● Apache commons logging ● SLF4J Perché astrarre? ● Per cambiare l'implementazione sottostante ● Per configurare in un solo punto ● Per formattare in modo omogeneo
  • 14. Astrazione, implementazione e bridging Altra API o framework bridge API di astrazione Adapter per Adapter per Adapter per Java logging log4j logback Java logging log4j logback
  • 15.
  • 16. Java logging – configurazione handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler .level = ALL java.util.logging.ConsoleHandler.level = INFO java.util.logging.FileHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
  • 17. Log4J esempio di configurazione tramite propeties log4j.rootLogger=debug, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=example.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
  • 18. Logback – configurazione xml <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
  • 19. Logback – configurazione groovy import ch.qos.logback.classic.encoder.PatternLayoutEncoder import ch.qos.logback.core.ConsoleAppender import static ch.qos.logback.classic.Level.DEBUG appender("STDOUT", ConsoleAppender) { encoder(PatternLayoutEncoder) { pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" } } root(DEBUG, ["STDOUT"])
  • 20. Logback – esempio di output 13:09:49.026 [userId=,userName=] c.m.p.database.JdbcConnectionProvider [ConnectionProvider.java:222] WARN: Could not create database abstraction for portofino org.postgresql.util.PSQLException: Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:123) ~[postgresql- 8.3-606.jdbc3.jar:na] at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-8.3- 606.jdbc3.jar:na] at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:124) ~[postgresql-8.3- 606.jdbc3.jar:na] at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30) ~[postgresql-8.3- 606.jdbc3.jar:na] at org.postgresql.jdbc3.Jdbc3Connection.<init>(Jdbc3Connection.java:24) ~[postgresql-8.3-606.jdbc3.jar:na] at org.postgresql.Driver.makeConnection(Driver.java:386) ~[postgresql-8.3-606.jdbc3.jar:na] at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-8.3-606.jdbc3.jar:na] at java.sql.DriverManager.getConnection(DriverManager.java:525) ~[na:1.5.0] at java.sql.DriverManager.getConnection(DriverManager.java:171) ~[na:1.5.0] at com.manydesigns.portofino.database.JdbcConnectionProvider.acquireConnection(JdbcConnectionProvider.java:80) ~[JdbcConnectionProvider.class:na] at com.manydesigns.portofino.database.ConnectionProvider.init(ConnectionProvider.java:165) ~[ConnectionProvider.class:na] at com.manydesigns.portofino.context.hibernate.HibernateContextImpl.loadConnections(HibernateContextImpl.java:137) [HibernateContextImpl.class:na] at com.manydesigns.portofino.servlets.PortofinoListener.createContext(PortofinoListener.java:328) [PortofinoListener.class:na] at com.manydesigns.portofino.servlets.PortofinoListener.contextInitialized(PortofinoListener.java:153) [PortofinoListener.class:na] at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135) [catalina.jar:6.0.29] at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630) [catalina.jar:6.0.29] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) [catalina.jar:6.0.29] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) [catalina.jar:6.0.29]
  • 21. Confronto implementazioni Java logging Log4j Logback Licenza JDK Apache EPL/LGPL Layout personalizzabili estensione sì sì Numero di livelli 7 6 5 Configurazione properties properties, xml, xml, API, API groovy Configurazione per test o no no sì condizionata Reload configurazione no Sì tramite thread sì senza thread Diagnostic context no Nested/Mapped Mapped Jar/versione negli stacktrace no no sì Diffusione scarsa ampia in crescita Stabilità di API/configurazione ferma stabile config cambiata Documentazione buona ottima ottima API minimale buona molto buona Messaggi parametrizzati no tramite log4j- sì extras
  • 22. Confronto API di astrazione Commons logging SLF4J Licenza Apache MIT Numero di livelli 6 6 Configurazione properties - Configurazione programmatica no no Diffusione ampia ampia Bridging no sì Binding dell'implementazione discovery statica
  • 23. Problematiche di logging su application server ● Presenza/assenza delle librerie di logging nell'application server: ● Presenza → conflitti con librerie in WEB-INF/lib ● Assenza → assenza della funzionalità ● Problemi di class loader ● Memory-leak
  • 24.
  • 25.
  • 26. Presenza delle librerie su vari appserver Java log4j logback JCL SLF4J logging Tomcat 6 JULI Jboss 5.1 Sì Sì Sì Sì Glassfish 3 Sì
  • 27. Soluzioni ● Usare una libreria di logging inusuale ● Essendo improbabile che l'appserver la contenga, includerla nella webapp è sicuro ● Usare Java logging standard ● Includere la libreria nella webapp sempre ● sperare che non vada in conflitto con l'appserver ● va bene con API stabili ● Includere o non includere la libreria nella webapp a seconda dell'appserver
  • 28. Riferimenti ● http://download.oracle.com/javase/1.4.2/docs/g uide/util/logging/overview.html http://commons.apache.org/logging/ ● http://logback.qos.ch/ ● http://logging.apache.org/log4j/ ● http://www.slf4j.org/ ● http://logging.apache.org/chainsaw/index.html ● http://articles.qos.ch/thinkAgain.html