Ne pas utiliser de Système.hors.println dans le code côté serveur

j'ai entendu que l'utilisation de System.out.println à des fins de journalisation est une très mauvaise pratique et cela peut forcer le serveur à échouer.

Je n'utilise pas cette approche mais je suis très intéressé de savoir pourquoi système.hors.println peut faire des choses si trash lorsqu'il est utilisé dans le code d'arrière-plan.

44
demandé sur tobiasbayer 2011-12-22 13:30:23

9 réponses

Système

.hors.println est une opération IO et prend donc beaucoup de temps. Le problème avec l'utiliser dans votre code est que votre programme va attendre jusqu'à ce que le println soit terminé. Cela peut ne pas être un problème avec les petits sites, mais dès que vous obtenez la charge ou de nombreuses itérations, vous sentirez la douleur.

la meilleure approche est d'utiliser un cadre de journalisation. Ils utilisent une file d'attente de messages et écrivent seulement si aucune autre sortie n'est en cours.

et une autre prestation est que vous pouvez configurer des fichiers journaux différents à des fins différentes. Quelque chose que votre équipe vous aimera.

pour en savoir plus:

45
répondu Lars 2017-05-23 12:26:00

c'est une mauvaise pratique parce que lorsque votre application va en Production, vous ne pouvez pas séparer les journaux d'application des journaux de serveur.

les équipes Prod veulent que vous sépariez les journaux produits par votre application de ceux du serveur app (tomcat, websphere, etc...): ils veulent pouvoir surveiller le serveur d'app de manière différente de l'application elle-même.

de plus, en utilisant le système.Hors, vous ne pouvez pas définir le niveau de log : dans la Production, vous ne voulez imprimer les informations de débogage.

18
répondu Jean-Philippe Briend 2011-12-22 09:34:30

Check out Adam Biens article dans L'édition Java Magazine Novembre/Décembre sur les stress testing jee6 applications - il est gratuit en ligne , vous n'avez qu'à vous y abonner.

à la page 43 Il montre, qu'un serveur d'applications qui parvient à traiter 1700 transactions par seconde tombe à seulement 800 en insérant un seul System.out.println avec chaîne fixe dans chacun.

15
répondu Alexander Rühl 2011-12-22 10:10:14

il est considéré comme mauvais parce que System.out.println(); mange plus de cpu et donc la sortie vient lent signifie des dommages à la performance. (En fait, chaque opération d'E/S mange cpu).

4
répondu Harry Joy 2011-12-22 09:41:42

la raison n'est pas que le serveur pourrait échouer, mais il pourrait être difficile de trouver une telle sortie sur le serveur. Vous devriez toujours utiliser une sorte de cadre de journalisation avec un comportement défini et un fichier de sortie.

3
répondu tobiasbayer 2011-12-22 09:35:38

pour un, avoir plusieurs requêtes sur votre serveur et imprimer la connexion System.out n'est pas une bonne pratique.

  1. tous les journaux sont imprimés à l'écran (descripteur de fichier). Il n'y a aucun moyen de revenir en arrière et lire le journal.
  2. System.out n'est pas synchronisé. Il doit y avoir une gestion de la concurrence pour gérer l'impression via System.out
  3. vous ne pouvez pas déterminer les niveaux de log à travers System.out . Vous ne pouvez pas séparer votre journal des niveaux de sorties séparées à la volée.

j'espère que cela aidera.

2
répondu Buhake Sindi 2011-12-22 09:39:48
Le programme
  1. attendra que l'impression soit terminée. Les Loggers utilisent la file d'attente de messages et écrivent seulement si aucune autre sortie n'est en cours.
  2. Système
  3. .hors.println (SOPs) are not thread safe (I. e asynchrone) Les bûcherons sont sécuritaires (I. e synchrone)
  4. Les Loggers
  5. sont hautement configurables Formatage a. , limitant le contenu des journaux que les exploitants peuvent atteindre b. Multiples à destination d'enregistrement du fichier, la console, la DB
  6. Pon écrire des journaux dans les fichiers journaux de Serveur. Nous devons garder les journaux d'application séparés des journaux du serveur car cela peut conduire à une défaillance du serveur
  7. les applications serveur qui parviennent à traiter 1700 transactions par seconde tombe à seulement 800 lors de l'insertion d'une seule Sop avec chaîne de correction dans chaque
2
répondu Yatish Balaji 2017-02-02 06:37:09

une autre raison est ce système.les sorties et les sorties sont des circuits imprimés, qui absorbent toutes les exceptions sous-jacentes. Voir cette méthode de PrintStreams:

/**
 * Writes the specified byte to this stream.  If the byte is a newline and
 * automatic flushing is enabled then the <code>flush</code> method will be
 * invoked.
 *
 * <p> Note that the byte is written as given; to write a character that
 * will be translated according to the platform's default character
 * encoding, use the <code>print(char)</code> or <code>println(char)</code>
 * methods.
 *
 * @param  b  The byte to be written
 * @see #print(char)
 * @see #println(char)
 */
public void write(int b) {
    try {
        synchronized (this) {
            ensureOpen();
            out.write(b);
            if ((b == '\n') && autoFlush)
                out.flush();
        }
    }
    catch (InterruptedIOException x) {
        Thread.currentThread().interrupt();
    }
    catch (IOException x) {
        trouble = true;
    }
}

/**
 * Flushes the stream and checks its error state. The internal error state
 * is set to <code>true</code> when the underlying output stream throws an
 * <code>IOException</code> other than <code>InterruptedIOException</code>,
 * and when the <code>setError</code> method is invoked.  If an operation
 * on the underlying output stream throws an
 * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
 * converts the exception back into an interrupt by doing:
 * <pre>
 *     Thread.currentThread().interrupt();
 * </pre>
 * or the equivalent.
 *
 * @return <code>true</code> if and only if this stream has encountered an
 *         <code>IOException</code> other than
 *         <code>InterruptedIOException</code>, or the
 *         <code>setError</code> method has been invoked
 */
public boolean checkError() {
    if (out != null)
        flush();
    if (out instanceof java.io.PrintStream) {
        PrintStream ps = (PrintStream) out;
        return ps.checkError();
    }
    return trouble;
}

donc une exception du flux sous-jacent est toujours consommée, et habituellement les gens n'appellent jamais checkError sur le système, donc ils ne savent même pas que quelque chose s'est passé.

1
répondu Gábor Lipták 2016-04-30 20:49:50

utiliser le standard out est une mauvaise pratique. Toutefois, si vous avez une bibliothèque, ou un code qui utilise le Système.et du Système.err vous pouvez écrire votre propre PrintStream qui journalise le nom du thread et l'information() et l'erreur() le texte à la place. Une fois que vous avez fait cela, vous pouvez être plus détendu sur l'utilisation du système.out comme il va écrire dans les journaux par exemple log4j.

Idéalement, vous utiliserez les logs appropriés directement esp pour la journalisation de niveau de débogage. À mon humble avis sa n'a pas beaucoup d'importance, pourvu que vous n'utilisiez pas le système intégré./err! (Une grande hypothèse certes)

si vous utilisez le système.qui est redirigé vers un fichier ou d'utiliser log4j ou Java Enregistreur pour écrire dans un fichier, la performance est presque exactement le même.

0
répondu Peter Lawrey 2011-12-22 10:21:58