Pourquoi ne pas utiliser java.util.logging?

351

Pour la première fois de ma vie, je me retrouve dans une position où j'écris une API Java qui sera open source. J'espère être inclus dans de nombreux autres projets.

Pour la journalisation, j'ai (et en effet les personnes avec qui je travaille) j'ai toujours utilisé JUL (java.util.logging) et je n'ai jamais eu de problème avec. Cependant, maintenant, je dois comprendre plus en détail ce que je dois faire pour le développement de mon API. J'ai fait des recherches à ce sujet et avec les informations que j'ai, je suis encore plus confus. D'où ce post.

Depuis que je viens de JUL, je suis partisan de cela. Ma connaissance du reste n'est pas si grande.

D'après les recherches que j'ai faites, j'ai trouvé ces raisons pour lesquelles les gens n'aiment pas JUL:

  1. "J'ai commencé à développer en Java bien avant la sortie de Sun de JUL et il était plus facile pour moi de continuer avec logging-framework-X plutôt que d'apprendre quelque chose de nouveau" . Hmm. Je ne plaisante pas, c'est en fait ce que les gens disent. Avec cet argument, nous pourrions tous faire du COBOL. (mais je peux certainement comprendre que c'est un mec paresseux moi-même)

  2. "Je n'aime pas les noms des niveaux de journalisation en JUL" . Ok, sérieusement, ce n'est tout simplement pas une raison suffisante pour introduire une nouvelle dépendance.

  3. "Je n'aime pas le format standard de la sortie de JUL" . Hmm. C'est juste une configuration. Vous n'avez même rien à faire au niveau du code. (c'est vrai, dans le passé, vous avez peut-être dû créer votre propre classe Formatter pour bien faire les choses).

  4. "J'utilise d'autres bibliothèques qui utilisent également logging-framework-X, donc j'ai pensé qu'il était plus facile de simplement utiliser celle-là" . C'est un argument circulaire, non? Pourquoi «tout le monde» utilise logging-framework-X et non JUL?

  5. "Tout le monde utilise logging-framework-X" . Pour moi, ce n'est qu'un cas particulier de ce qui précède. La majorité n'a pas toujours raison.

La vraie grande question est donc pourquoi pas JUL? . Qu'est-ce que j'ai manqué? La raison d'être des façades de journalisation (SLF4J, JCL) est que plusieurs implémentations de journalisation ont existé historiquement et que la raison de cela remonte vraiment à l'époque d'avant JUL telle que je la vois. Si JUL était parfait, les façades d'abattage n'existeraient pas, ou quoi? Pour rendre les choses plus confuses, JUL est dans une certaine mesure une façade elle-même, permettant aux gestionnaires, aux formateurs et même au LogManager d'être échangés.

Plutôt que d'embrasser plusieurs façons de faire la même chose (enregistrement), ne devrions-nous pas nous demander pourquoi elles étaient nécessaires en premier lieu? (et voir si ces raisons existent toujours)

Ok, mes recherches jusqu'à présent ont conduit à quelques choses que je peux voir peuvent être de vrais problèmes avec JUL:

  1. Performance . Certains disent que les performances du SLF4J sont supérieures aux autres. Cela me semble être un cas d'optimisation prématurée. Si vous devez enregistrer des centaines de mégaoctets par seconde, je ne suis pas sûr que vous soyez de toute façon sur la bonne voie. JUL a également évolué et les tests que vous avez faits sur Java 1.4 peuvent ne plus être vrais. Vous pouvez en savoir plus ici et ce correctif a été intégré à Java 7. Beaucoup parlent également de la surcharge de la concaténation de chaînes dans les méthodes de journalisation. Cependant, la journalisation basée sur un modèle évite ce coût et existe également en juillet. Personnellement, je n'écris jamais vraiment une journalisation basée sur un modèle. Trop paresseux pour ça. Par exemple, si je fais cela avec JUL:

    log.finest("Lookup request from username=" + username 
       + ", valueX=" + valueX
       + ", valueY=" + valueY));

    mon IDE m'avertira et me demandera la permission de le changer en:

    log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", 
       new Object[]{username, valueX, valueY});

    .. que j'accepterai bien sûr. Permission accordée ! Merci de votre aide.

    Donc je n'écris pas de telles déclarations moi-même, c'est fait par l'IDE.

    En conclusion sur la question de la performance, je n'ai rien trouvé qui puisse suggérer que la performance de JUL n'est pas correcte par rapport à la concurrence.

  2. Configuration à partir de classpath . JUL prêt à l'emploi ne peut pas charger un fichier de configuration à partir du chemin de classe. Il suffit de quelques lignes de code pour le faire. Je peux voir pourquoi cela peut être ennuyeux mais la solution est courte et simple.

  3. Disponibilité des gestionnaires de sortie . JUL est livré avec 5 gestionnaires de sortie prêts à l'emploi: console, flux de fichiers, socket et mémoire. Ceux-ci peuvent être étendus ou de nouveaux peuvent être écrits. Cela peut par exemple être écrit dans UNIX / Linux Syslog et le journal des événements Windows. Personnellement, je n'ai jamais eu cette exigence et je ne l'ai jamais vue utilisée, mais je peux certainement comprendre pourquoi elle peut être une fonctionnalité utile. Logback est fourni avec un appender pour Syslog par exemple. Je dirais néanmoins que

    1. 99,5% des besoins en destinations de sortie sont couverts par ce qui se trouve dans JUL prêt à l'emploi.
    2. Les besoins spéciaux pourraient être pris en charge par des gestionnaires personnalisés en plus de JUL plutôt qu'en plus d'autre chose. Il n'y a rien pour moi qui suggère qu'il faut plus de temps pour écrire un gestionnaire de sortie Syslog pour JUL que pour un autre framework de journalisation.

Je suis vraiment préoccupé par le fait que j'ai oublié quelque chose. L'utilisation de façades de journalisation et d'implémentations de journalisation autres que JUL est si répandue que je dois en conclure que c'est moi qui ne comprends tout simplement pas. Ce ne serait pas la première fois, je le crains. :-)

Alors, que dois-je faire avec mon API? Je veux que ça réussisse. Je peux bien sûr simplement "suivre le courant" et implémenter SLF4J (qui semble le plus populaire de nos jours) mais pour moi-même, j'ai encore besoin de comprendre exactement ce qui ne va pas avec le JUL d'aujourd'hui qui mérite tout le fuzz? Vais-je me saboter en choisissant JUL pour ma bibliothèque?

Test des performances

(section ajoutée par nolan600 le 07-JUL-2012)

Il y a une référence ci-dessous de Ceki sur le paramétrage de SLF4J étant 10 fois ou plus rapide que JUL. J'ai donc commencé à faire des tests simples. À première vue, l'affirmation est certainement correcte. Voici les résultats préliminaires (mais lisez la suite!):

  • Temps d'exécution SLF4J, backend Logback: 1515
  • Temps d'exécution SLF4J, backend JUL: 12938
  • Temps d'exécution JUL: 16911

Les nombres ci-dessus sont msec donc moins c'est mieux. Donc, une différence de performances de 10 fois est d'abord assez proche. Ma première réaction: c'est beaucoup!

Voici l'essentiel du test. Comme on peut le voir, un entier et une chaîne sont construits dans une boucle qui est ensuite utilisée dans l'instruction log:

    for (int i = 0; i < noOfExecutions; i++) {
        for (char x=32; x<88; x++) {
            String someString = Character.toString(x);
            // here we log 
        }
    }

(Je voulais que l'instruction log ait à la fois un type de données primitif (dans ce cas, un int) et un type de données plus complexe (dans ce cas, une chaîne). Je ne suis pas sûr que cela soit important mais vous l'avez.)

L'instruction de journal pour SLF4J:

logger.info("Logging {} and {} ", i, someString);

L'instruction de journal pour JUL:

logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});

La JVM a été «réchauffée» avec le même test exécuté une fois avant la mesure proprement dite. Java 1.7.03 a été utilisé sur Windows 7. Les dernières versions de SLF4J (v1.6.6) et Logback (v1.0.6) ont été utilisées. Stdout et stderr ont été redirigés vers un périphérique nul.

Cependant, attention maintenant, il s'avère que JUL passe la plupart de son temps getSourceClassName()car JUL affiche par défaut le nom de la classe source dans la sortie, contrairement à Logback. Nous comparons donc des pommes et des oranges. Je dois refaire le test et configurer les implémentations de journalisation de manière similaire afin qu'elles produisent réellement le même contenu. Je soupçonne cependant que SLF4J + Logback sortira toujours en tête mais loin des chiffres initiaux indiqués ci-dessus. Restez à l'écoute.

Btw: Le test était la première fois que je travaillais avec SLF4J ou Logback. Une expérience agréable. JUL est certainement beaucoup moins accueillant lorsque vous débutez.

Test des performances (partie 2)

(section ajoutée par nolan600 le 08-JUL-2012)

En fin de compte, peu importe pour les performances la façon dont vous configurez votre modèle dans JUL, c'est-à-dire s'il inclut ou non le nom de la source. J'ai essayé avec un motif très simple:

java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"

et cela n'a pas du tout changé les horaires ci-dessus. Mon profileur a révélé que l'enregistreur passait encore beaucoup de temps à appeler getSourceClassName()même si cela ne faisait pas partie de mon schéma. Le motif n'a pas d'importance.

Je conclus donc sur la question des performances qu'au moins pour l'instruction de journal basée sur un modèle testé, il semble y avoir environ un facteur de 10 dans la différence de performances réelles entre JUL (lent) et SLF4J + Logback (rapide). Tout comme Ceki l'a dit.

Je peux également voir une autre chose, à savoir que l' getLogger()appel de SLF4J est beaucoup plus cher que idem pour JUL. (95 ms vs 0,3 ms si mon profileur est précis). C'est logique. SLF4J doit faire un certain temps sur la liaison de l'implémentation de journalisation sous-jacente. Cela ne me fait pas peur. Ces appels devraient être quelque peu rares dans la durée de vie d'une application. La solidité doit être dans les appels de journal réels.

Conclusion finale

(section ajoutée par nolan600 le 08-JUL-2012)

Merci pour toutes vos réponses. Contrairement à ce que je pensais au départ, j'ai fini par décider d'utiliser SLF4J pour mon API. Ceci est basé sur un certain nombre de choses et sur votre contribution:

  1. Il offre la flexibilité de choisir l'implémentation des journaux au moment du déploiement.

  2. Problèmes avec le manque de flexibilité de la configuration de JUL lorsqu'elle est exécutée à l'intérieur d'un serveur d'applications.

  3. SLF4J est certainement beaucoup plus rapide comme détaillé ci-dessus en particulier si vous le couplez avec Logback. Même si ce n'était qu'un test approximatif, j'ai des raisons de croire que beaucoup d'efforts ont été consacrés à l'optimisation sur SLF4J + Logback que sur JUL.

  4. Documentation. La documentation du SLF4J est tout simplement beaucoup plus complète et précise.

  5. Flexibilité du motif. Comme je l'ai fait les tests, j'ai décidé d'avoir JUL imiter le modèle par défaut de Logback. Ce modèle inclut le nom du thread. Il s'avère que JUL ne peut pas faire cela hors de la boîte. Ok, je ne l'ai pas manqué jusqu'à présent, mais je ne pense pas que ce soit une chose qui devrait manquer dans un cadre de log. Période!

  6. La plupart (ou beaucoup) de projets Java utilisent aujourd'hui Maven, donc l'ajout d'une dépendance n'est pas si important, surtout si cette dépendance est plutôt stable, c'est-à-dire qu'elle ne change pas constamment son API. Cela semble être vrai pour SLF4J. Le pot SLF4J et ses amis sont également de petite taille.

Donc, la chose étrange qui s'est produite, c'est que j'ai été assez contrarié par JUL après avoir un peu travaillé avec SLF4J. Je regrette toujours que ce soit le cas avec JUL. JUL est loin d'être parfait mais fait le travail. Mais pas assez bien. La même chose peut être dite à Propertiestitre d'exemple, mais nous ne pensons pas à l'abstraire pour que les gens puissent brancher leur propre bibliothèque de configuration et ce que vous avez. Je pense que la raison en est que cela Propertiesvient juste au-dessus de la barre alors que le contraire est vrai pour JUL d'aujourd'hui ... et dans le passé, il était à zéro parce qu'il n'existait pas.

peterh
la source
8
Je ne poserai pas de conclusion, car cette question bien présentée est intéressante, mais elle est limite si vous lisez la FAQ: il sera difficile de trouver une réponse unique définitive non basée sur des opinions.
Denys Séguret
Ce que vous avez peut-être manqué, c'est que de nombreux auteurs de framework ont ​​abandonné l'utilisation de JUL et qu'il est donc souvent plus difficile de l'utiliser si vous ne faites pas simplement de la vanille java.
Denys Séguret
3
Il est trompeur d'utiliser le terme générique "logging-framework-X" lorsqu'il fait référence aux cadres de journalisation populaires antérieurs à juillet. Vous devez utiliser "log4j" dans ce cas. D'autres frameworks populaires tels que SLF4J et logback sont venus bien après la sortie de juillet.
Ceki
1
@Acuariano. Le projet Netty utilise simplement Reflection pour tester le cadre de journalisation disponible sur classpath. Voir ici pour la source. Tu vois InternalLoggerFactory.java.
peterh
1
@xenoterracide encore plus important serait une mise à jour de Java 9, comme il l'a présenté java.lang.System.Logger, qui est une interface , qui peut être redirigée vers le cadre de journalisation réel que vous souhaitez, tant que ce cadre est rattrapé et fournit une implémentation de cette interface. Combiné à la modularisation, vous pouvez même déployer une application avec un JRE intégré ne contenant pas java.util.logging, si vous préférez un framework différent.
Holger

Réponses:

207

Avertissement : je suis le fondateur des projets log4j, SLF4J et logback.

Il y a des raisons objectives de préférer SLF4J. Pour un, SLF4J permet à l'utilisateur final de choisir le cadre de journalisation sous-jacent . De plus, les utilisateurs avertis ont tendance à préférer la déconnexion qui offre des capacités au-delà de log4j , avec jul en retard. La fonctionnalité jul peut être suffisante pour certains utilisateurs, mais pour beaucoup d'autres, elle ne l'est tout simplement pas. En bref, si la journalisation est importante pour vous, vous voudrez utiliser SLF4J avec logback comme implémentation sous-jacente. Si la journalisation est sans importance, jul est très bien.

Cependant, en tant que développeur oss, vous devez prendre en compte les préférences de vos utilisateurs et pas seulement les vôtres. Il s'ensuit que vous devez adopter SLF4J non pas parce que vous êtes convaincu que SLF4J est meilleur que juillet mais parce que la plupart des développeurs Java actuellement (juillet 2012) préfèrent SLF4J comme API de journalisation. Si finalement vous décidez de ne pas vous soucier de l'opinion populaire, tenez compte des faits suivants:

  1. ceux qui préfèrent jul le font par commodité car jul est fourni avec le JDK. À ma connaissance, il n'y a pas d'autres arguments objectifs en faveur de jul
  2. votre propre préférence pour juillet est juste cela, une préférence .

Ainsi, tenir les «faits concrets» au-dessus de l'opinion publique, bien qu'apparemment courageux, est une erreur logique dans ce cas.

S'il n'est toujours pas convaincu, JB Nizet fait un argument supplémentaire et puissant:

Sauf que l'utilisateur final aurait déjà pu faire cette personnalisation pour son propre code, ou une autre bibliothèque qui utilise log4j ou logback. jul est extensible, mais devoir étendre logback, jul, log4j et Dieu ne sait que quel autre cadre de journalisation car il utilise quatre bibliothèques qui utilisent quatre cadres de journalisation différents est encombrant. En utilisant SLF4J, vous lui permettez de configurer les frameworks de journalisation qu'il souhaite, pas celui que vous avez choisi. N'oubliez pas qu'un projet typique utilise une myriade de bibliothèques, et pas seulement la vôtre .

Si pour quelque raison que ce soit, vous détestez l'API SLF4J et que son utilisation étouffera le plaisir de votre travail, alors allez-y pour jul Après tout, il existe des moyens de rediriger jul vers SLF4J .

Soit dit en passant, la paramétrisation jul est au moins 10 fois plus lente que celle du SLF4J, ce qui finit par faire une différence notable.

Ceki
la source
2
@Ceki, vous voudrez peut-être développer un peu votre avertissement afin qu'il mentionne votre rôle actuel dans les projets log4j, slf4j et logback. La raison est naturellement d'expliquer votre parti pris.
Thorbjørn Ravn Andersen
2
Existe-t-il une prise en charge de l'affirmation selon laquelle la plupart des développeurs Java préfèrent SLF4J comme API de journalisation?
Olivier Cailloux
3
L'essence de mon article est que différents développeurs ont des préférences différentes, ce qui semble incontestable. Oui?
Ceki
1
Honnêtement, j'aimerais voir les benchmarks 2018 sur Java 11 (ou quoi que ce soit) et contre log4j2 en mode asynchrone.
xenoterracide
5
Je suis ici, en utilisant SLF4J, et je dois encore faire face à tous les autres cadres de journalisation que les autres bibliothèques utilisent. L'utilisation de SLF4J ne résout pas le problème des enregistreurs hétérogènes, il ne fait qu'empirer les choses. xkcd.com/927
Charlie
34
  1. java.util.logginga été introduit dans Java 1.4. Il y avait des utilisations pour la journalisation avant cela, c'est pourquoi de nombreuses autres API de journalisation existent. Ces API étaient largement utilisées avant Java 1.4 et avaient donc une grande part de marché qui n'était pas simplement tombée à 0 lors de la sortie de 1.4.

  2. JUL n'a pas commencé très bien, bon nombre des choses que vous avez mentionnées étaient bien pires en 1,4 et ne se sont améliorées qu'en 1,5 (et je suppose également en 6, mais je ne suis pas trop sûr).

  3. JUL n'est pas bien adapté pour plusieurs applications avec des configurations différentes dans la même JVM (pensez à plusieurs applications Web qui ne devraient pas interagir). Tomcat doit sauter à travers quelques cerceaux pour que cela fonctionne (réimplémenter efficacement JUL si j'ai bien compris).

  4. Vous ne pouvez pas toujours influencer le cadre de journalisation utilisé par vos bibliothèques. Par conséquent, l'utilisation de SLF4J (qui n'est en fait qu'une couche API très mince au-dessus des autres bibliothèques) permet de garder une image quelque peu cohérente de tout le monde de la journalisation (vous pouvez donc décider du cadre de journalisation sous-jacent tout en conservant la journalisation de la bibliothèque dans le même système).

  5. Les bibliothèques ne peuvent pas changer facilement. Si une version précédente d'une bibliothèque utilisait logging-library-X, elle ne peut pas facilement basculer vers logging-library-Y (par exemple JUL), même si cette dernière est clairement superflue: tout utilisateur de cette bibliothèque devrait apprendre le nouveau cadre de journalisation et (au moins) reconfigurer leur journalisation. C'est un gros non, surtout quand cela n'apporte aucun gain apparent à la plupart des gens.

Cela dit, je pense que JUL est au moins une alternative valable aux autres cadres de journalisation de nos jours.

Joachim Sauer
la source
1
Merci Joachim, j'apprécie votre message. Vos (1) et (2) ne sont pour moi que de l'histoire. Il y a longtemps. Votre (4) en est la conséquence et devient alors ce que j'appelle un argument cyclique. Votre (3) est cependant vraiment intéressant. Vous êtes peut-être sur quelque chose? Mais cela n'affecterait que ceux qui construisent des conteneurs d'application qui, au bout du compte, sont très peu de gens. Ou quoi?
peterh
3
Eh bien, qui ignore l'histoire est condamné à la répéter ;-) L'histoire est très pertinente dans le développement de logiciels. Les gens ne se déplacent pas trop vite et le remplacement des bibliothèques tierces existantes par des API standard ne fonctionne bien que si les API standard fonctionnent au moins aussi bien que les bibliothèques tierces. Et ils ne l'ont pas fait initialement (et sans doute toujours pas dans certains cas).
Joachim Sauer
Joachim, je m'intéresse à ceux "sans doute toujours pas dans certains cas" que vous mentionnez. C'est là que la viande doit être. Le remplacement d'une bibliothèque d'enregistreurs dans votre code existant est assez trivial et peut être automatisé de nos jours. SLF4J a un outil pour cela, ce qui prouve mon point de vue. Je pense donc qu'une bibliothèque massive écrite en 2002 avec log4j pourrait être convertie en JUL en quelques minutes avec un outil automatisé. (Je ne sais pas s'il en existe un, cependant). Alors pourquoi ça n'arrive pas?
peterh
3
@ nolan6000: Je ne connais pas assez les détails pour entrer dans les détails de cette phrase, et ce n'est pas vraiment le point que je fais. Même si JUL est maintenant à égalité avec les cadres tiers, l'inertie et les infrastructures existantes sont toujours une bonne raison de ne pas changer. Par exemple, si la bibliothèque X utilisait slf4j dans la version 1.1, le passage à JUL dans 1.2 (ou même 2.0) serait un problème majeur pour de nombreux utilisateurs (qui ont déjà correctement configuré l'ancien système et devraient le refaire sans gain apparent) .
Joachim Sauer
@ nolan6000 même si vous ne vous souciez pas de l'histoire, les bibliothèques que vous utilisez dans vos applications le sont très certainement. Pas amusant de devoir supprimer une bibliothèque simplement parce qu'elle utilise un cadre de journalisation différent du vôtre.
Thorbjørn Ravn Andersen
29

À mon humble avis, le principal avantage de l'utilisation d'une façade de journalisation comme slf4j est que vous laissez l'utilisateur final de la bibliothèque choisir l'implémentation concrète de journalisation qu'il souhaite, plutôt que d'imposer votre choix à l'utilisateur final.

Peut-être qu'il a investi du temps et de l'argent dans Log4j ou LogBack (formateurs spéciaux, appenders, etc.) et préfère continuer à utiliser Log4j ou LogBack, plutôt que de configurer jul. Pas de problème: slf4j le permet. Est-ce un choix judicieux d'utiliser Log4j au cours de juillet? Peut-être peut-être pas. Mais tu t'en fous. Laissez l'utilisateur final choisir ce qu'il préfère.

JB Nizet
la source
Merci JB. Ma question est de savoir si j'impose vraiment autant à l'utilisateur / implémenteur de ma bibliothèque en lui imposant JUL? S'il n'est pas satisfait, par exemple, des gestionnaires de sortie standard de JUL, il peut simplement les échanger pour les siens au moment du déploiement, comme je le vois. Je ne vois pas vraiment JUL comme une camisole de force. Il me semble être aussi flexible et extensible que les autres.
peterh
12
Sauf que l'utilisateur final aurait déjà pu faire cette personnalisation pour son propre code, ou une autre bibliothèque qui utilise log4j ou LogBack. jul est extensible, mais devoir étendre LogBack, jul, log4j et Dieu ne sait que quel autre cadre de journalisation car il utilise 4 bibliothèques qui utilisent 4 cadres de journalisation différents est encombrant. En utilisant slf4j, vous lui permettez de configurer les cadres de journalisation qu'il souhaite. pas celui que vous avez choisi. N'oubliez pas que les projets typiques utilisent une myriade de bibliothèques, et pas seulement la vôtre.
JB Nizet
6

J'ai commencé, comme vous je suppose, à utiliser JUL parce que c'était le plus facile à démarrer immédiatement. Au fil des ans, cependant, j'ai fini par souhaiter avoir passé un peu plus de temps à choisir.

Mon principal problème est maintenant que nous avons une quantité substantielle de code de «bibliothèque» qui est utilisé dans de nombreuses applications et ils utilisent tous JUL. Chaque fois que j'utilise ces outils dans une application de type service Web, la journalisation disparaît ou disparaît dans un endroit imprévisible ou étrange.

Notre solution a été d'ajouter une façade au code de la bibliothèque, ce qui signifie que les appels de journal de bibliothèque n'ont pas changé mais ont été redirigés dynamiquement vers le mécanisme de journalisation disponible. Lorsqu'ils sont inclus dans un outil POJO, ils sont dirigés vers JUL mais lorsqu'ils sont déployés en tant qu'application Web, ils sont redirigés vers LogBack.

Notre regret - bien sûr - est que le code de la bibliothèque n'utilise pas la journalisation paramétrée, mais cela peut maintenant être modifié en fonction des besoins.

Nous avons utilisé slf4j pour construire la façade.

OldCurmudgeon
la source
1
Une raison pour laquelle vous n'avez pas simplement utilisé le package "rediriger java.util.logging vers slf4j" dans la distribution slf4j?
Thorbjørn Ravn Andersen
2
Nous l'avons fait, mais avec peu de valeur car le principal avantage du passage à slf4j est une journalisation paramétrée efficace. Si nous l'avions utilisé depuis le début, nous n'aurions eu aucun travail à faire maintenant.
OldCurmudgeon
1
Je suis d'accord que c'est le fruit bas de slf4j.
Thorbjørn Ravn Andersen
3

J'ai exécuté jul contre slf4j-1.7.21 sur logback-1.1.7, sortie sur un SSD, Java 1.8, Win64

jul a exécuté 48449 ms, déconnexion 27185 ms pour une boucle de 1M.

Pourtant, un peu plus de vitesse et une API un peu plus agréable ne valent pas 3 bibliothèques et 800K pour moi.

package log;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogJUL
{
    final static Logger logger = Logger.getLogger(LogJUL.class.getSimpleName());

    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            Object[] o = { lc };

            logger.log(Level.INFO,"Epoch time {0}", o);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }
}

et

package log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogSLF
{
    static Logger logger = LoggerFactory.getLogger(LogSLF.class);


    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            logger.info("Epoch time {}", lc);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }

}
weberjn
la source
3
Vous ne comparez pas comme pour comme. Pourquoi créez-vous explicitement un tableau pour juillet? Je suppose que c'est parce que slf4j n'a pas de surcharge d'un argument logger.info(). Donc, vous êtes délibérément paralysant les performances de juillet pour compenser une lacune dans l'interface de slf4j. Vous devriez plutôt coder les deux méthodes de la façon dont elles sont codées de manière idiomatique.
Klitos Kyriacou
2
Vous l'avez mal compris. Vous n'avez pas besoin d'utiliser 800K supplémentaires. Le consensus est que l' api SLF4J très mince vaut la peine d'être utilisé car alors vous (ou d'autres qui réutilisent peut-être un jour votre code!) Vous pouvez basculer librement entre JUL, Logback, Log4j etc. SLF4J n'est que ~ 28K. Le pont SLF4J vers JUL (slf4j-jdk ... jar) est seulement ~ 9K.
riskop