Ciao a tutti.
Come esercizio (o sega) mentale ho pensato a come avrei implementato una
libreria per logging fluente *ma usando kotlin invece di java.*
La libreria avrebbe un unico file dove aggiungo alcuni metodi alla classe
Logger:
---------------------------------------------
package fluentlogger
import org.slf4j.Logger
fun Logger.ifTrace() = if(this.isTraceEnabled) this else null
fun Logger.ifDebug() = if(this.isDebugEnabled) this else null
fun Logger.ifInfo() = if(this.isInfoEnabled) this else null
fun Logger.ifWarn() = if(this.isWarnEnabled) this else null
---------------------------------------------
Ecco un esempio di come come verrebbe usata:
---------------------------------------------
package example
import fluentlogger.*
private val log = org.slf4j.LoggerFactory.getLogger("myLogger")
fun main(args: Array<String>) {
val file = java.io.File("myFile.txt")
log.ifTrace()?.trace("Writing file ${file.absolutePath}")
try {
file.writeText("Hello World")
log.ifDebug()?.debug("File ${file.absolutePath} written")
} catch (e: Exception) {
log.error("Error writing file ${file.absolutePath}", e)
}
}
---------------------------------------------
*Nota*: non c'e nessun bisogno del *lazy* e non ci sarebbe neanche bisogno
di *slf4j*, *log4j* andrebbe bene lo stesso, visto che il messaggio viene
costruito solo se necessario.
Gli unici costi in termini di performance che vedo sono:
- un ulteriore chiamata a funzione per controllare il livello del
logger, visto che wrappo i metodi *ifDebugEnabled* etc...
- un ulteriore if per controllare se il logger è nullo fatto con
l'operatore kotlin "?"
Non so se la mia libreria potrebbe essere interessante ma magari convinco
qualcuno a passare a kotlin :D
On Tue, Jan 8, 2019 at 9:20 PM Simone Bordet [email protected]
[it-torino-java-jug] <[email protected]> wrote:
>
>
> Ciao,
>
> On Tue, Jan 8, 2019 at 8:32 PM Paolo Mossino [email protected]
> [it-torino-java-jug] <[email protected]> wrote:
> > Penso sia interessante iniziare la discussione non tanto
> dall'implementazione di Federico, ma dal questo articolo sul design di
> Flogger:
> > https://google.github.io/flogger/anatomy.html
> >
> > Se ho letto bene, una delle principali obiezioni di Simone era su:
> > -----XXX-----XXX-----
> > paghi l'if (dentro atDebug()), string concatenation, boxing e varargs
> array
> > -----XXX-----XXX-----
> >
> > Mi pare flogger ignori completamente l'aspetto della string
> concatenation (con un implicito "non usarla"),
>
> Come API designer, così sono sicuro al 100% che non verrà usata - come no.
>
> Sempre da quella pagina:
>
> "the allocation of a small instance to hold contextual information for
> the log statement is not significant compared to the work we will do
> later"
>
> Però non ci sono benchmark results, nessuna definizione di "work we
> will do later".
> Oh shit, allochiamo perché abbiamo fatto il design delle API così,
> però scriviamo che tanto "is not significant" e siamo a posto.
> La tecnica dello struzzo funziona sempre ;)
>
> > e risolve le ultime due scrivendo scrivendo una bella valanga di metodi:
> > https://github.com/google/flogger/blob/master/api/src/
> main/java/com/google/common/flogger/LoggingApi.java#L289
>
> Non "risolve" nulla.
> Copre alcuni casi, ma non tutti.
> Niente lambda.
> 106 metodi per una interfaccia di logging.
>
> > Se partiamo da codice come quello descritto da Federico, dove:
> > -----XXX-----XXX-----
> > Raramente ho visto usare "if (isDebugEnabled())" nel codice delle
> applicazioni su cui ho lavorato
> > -----XXX-----XXX-----
> >
> > se usi una "tradizionale" libreria di logging, senza nessun
> isLevelEnabled() guard, non avresti comunque gli stessi problemi di "string
> concatenation, boxing e varargs array" ad ogni chiamata?
>
> Certo che li avresti.
>
> Il fatto che Federico non abbia visto spesso if (isDebugEnabled()) non
> si applica a tutti i casi.
> In Jetty, è invece usato *sempre* e abbiamo anche misurato gli effetti
> di non metterlo e sono devastanti per le performances.
>
> Invece, if (isDebugEnabled()) è ottimizzato molto bene da JITs e CPU..
>
> Però davvero, quanto tempo spende lo sviluppatore medio a leggere
> linee di codice che sono log statements, comparate alle linee di
> codice del business?
> Vale veramente la pena di fare tutto 'sto sforzo quando il cervello
> "skippa" la linea di log appena vede il logging pattern, che sia "if
> (isDebug...<brain_skip>" oppure "log.atDebu...<brain_skip>", così come
> skippa i javadocs, i commenti, ecc.
> Occorre uno sforzo di concentrazione per leggere quello che il
> cervello "skippa" a causa del riconoscimento di pattern di "lesser
> importance"; se tanto lo sforzo di concentrazione lo fai, vedo poca
> differenza a usare plain SLF4J oppure Flogger o quella di Federico.
>
> --
> Simone Bordet
> ---
> Finally, no matter how good the architecture and design are,
> to deliver bug-free software with optimal performance and reliability,
> the implementation technique must be flawless. Victoria Livschitz
>
>