Heim  >  Artikel  >  Java  >  Effektive Protokollierung für die Funktion

Effektive Protokollierung für die Funktion

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-05 14:08:02947Durchsuche

Effective Logging for Function

Die Beherrschung der Protokollierung auf Funktionsebene ist ein entscheidender Schritt zum Verständnis und zur Implementierung einer umfassenden Protokollierung für ganze Softwaresysteme. Indem wir uns auf die granulare Ebene der Funktionen konzentrieren, können wir eine solide Grundlage schaffen, die die Skalierung auf komplexe Systeme zum Kinderspiel macht.

Hier sind fünf wichtige Punkte, die Sie beim Schreiben von Protokollen für eine Funktion beachten sollten:

  1. Geben Sie den Ursprung des Protokolls an:

    • Notieren Sie sich immer die Quelle des Protokolls. Dazu können der Zeitpunkt der Erstellung, der Name der Datei, die Funktion, mit der sie verknüpft ist, und viele andere Details gehören. Dies ist bei der Fehlerbehebung hilfreich, da sich der Entwickler auf eine bestimmte Datei oder Funktion konzentrieren kann.
  2. Schreiben Sie mit Blick auf das Debuggen:

    • Berücksichtigen Sie beim Schreiben von Protokollen mögliche Probleme, die auftreten könnten. Protokolle sollten so geschrieben werden, dass sie bei der Lösung dieser Probleme helfen, falls sie auftreten.
  3. Eine Geschichte erzählen:

    • Protokolle sollten wie eine Geschichte sein, die sich auf das Wesentliche konzentriert, aber alle wichtigen Details abdeckt. Jede Funktion sollte ihre eigene Erzählung haben, beginnend mit den empfangenen Argumenten und endend mit den zurückgegebenen Daten. Das Protokoll kann die Ausführungszeit, alle aufgerufenen inneren Funktionen, die empfangenen Eingaben und die zurückgegebenen Ausgaben enthalten.
  4. Protokolle gründlich testen:

    • Genau wie die Testfunktion nach Abschluss sollten auch Protokolle getestet werden. Stellen Sie sicher, dass in den Protokollen sowohl für erfolgreiche als auch für erfolglose Fälle die richtigen Informationen angezeigt werden. Betrachten Sie Protokolle immer aus der Perspektive von jemandem, der versucht, ein Problem zu beheben.
  5. Überprotokollierung vermeiden:

    • Nicht alles sollte protokolliert werden. Sensible Informationen, insbesondere wenn es sich um Benutzerdaten handelt, sollten weggelassen werden. Anstatt beispielsweise alle Benutzerdetails zu protokollieren, sollten nur die Benutzer-ID oder die im Code verwendeten Informationen protokolliert werden.

Denken Sie daran, sich auf der richtigen Ebene anzumelden:

  • INFO – Protokolliert nicht vertrauliche Details zum Betrieb der App.
  • WARNUNG – Zeigt potenzielle Probleme an, ohne die Benutzererfahrung zu beeinträchtigen.
  • FEHLER – Weist auf schwerwiegende Probleme hin, die sich auf die Benutzererfahrung auswirken.
  • FATAL – Kennzeichnet schwerwiegende Fehler, die die Benutzererfahrung erheblich beeinträchtigen.
  • DEBUG – Stellt Debugging-Informationen für Entwickler bereit.

Best Practices für die Funktionsprotokollierung

Wesentliche Elemente in einer Protokollzeichenfolge: Die Einbeziehung von Timestamp, ApplicationName, FileName, FunctionName , LEVEL und alle anderen relevanten Details können die Effektivität von Protokollen für eine Anwendung erheblich verbessern. Diese Elemente liefern entscheidenden Kontext und erleichtern die Verfolgung des Ereignisflusses, insbesondere beim Debuggen oder Überwachen der Anwendung. Denken Sie daran, dass das Ziel darin besteht, Protokolle zu erstellen, die informativ und nützlich sind und gleichzeitig Datenschutz- und Sicherheitsaspekte respektieren.

Die Nachricht sollte Folgendes vermitteln:die beabsichtigte Aktion, den Initiator der Aktion sowie den Input und Output.

Berücksichtigen Sie die folgenden unstrukturierten Protokolleinträge:


2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: Fetching mailing list 14777
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User 3654 opted out
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User 1334563 plays 4 of spades in game 23425656


Durch die Strukturierung dieser Einträge als JSON verbessern wir die Lesbarkeit und erleichtern das Parsen:


2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: Fetching mailing list {"listid":14777}
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User opted out {"userid":3654}
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User plays {'user':1334563, 'card':'4 of spade', 'game':23425656}


Durch die Einhaltung dieser Vorgehensweisen können wir sicherstellen, dass unsere Protokolle informativ, leicht lesbar und für die Fehlerbehebung wertvoll sind.

Codebeispiel und Best Practices

  • Konsistenz und Einheitlichkeit der Protokolle aufrechterhalten: Es ist wichtig sicherzustellen, dass die Protokolle im gesamten Programm konsistent bleiben, unabhängig von der Anzahl der Entwickler, die den Code schreiben. Dies erleichtert das Debuggen, das Verständnis des Betriebsablaufs und eine bessere Nachvollziehbarkeit der Codeausführung.
  • Erstellen Sie eine Protokollierungsvorlage und verwenden Sie dasselbe Protokollierungsmuster: Entwickeln Sie eine Standardprotokollierungsvorlage für das gesamte Team und ermutigen Sie jeden Entwickler im Team, dasselbe Protokollierungsmuster zu befolgen. Dies fördert die Einheitlichkeit und erleichtert das Lesen und Verstehen der Protokolle.
  • Stellen Sie Beispielfunktionen bereit und verweisen Sie darauf: Stellen Sie einige Beispielfunktionen zur Verfügung, die gute Protokollierungspraktiken im Code demonstrieren. Diese können den Entwicklern als Referenz dienen. Ermöglichen Sie Entwicklern, sich beim Schreiben ihres eigenen Codes auf diese Beispiele zu beziehen. Dies hilft ihnen, die etablierten Protokollierungspraktiken einzuhalten und die Konsistenz aufrechtzuerhalten.

Hier ist ein Beispiel:


import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class UserService {

    private static final Logger logger = LogManager.getLogger(UserService.class);
    private Database database;

    public UserService(Database database) {
        this.database = database;
    }

    public int getTotalLikesInLast30Days(String userId) {
        logger.info("Request received to get all total likes in last 30 days 
                for: {userId: " + userId + "}");
        long startTime = System.nanoTime();

        try {
            logger.debug("Fetching user with id: {userId: " + userId + "}");
            User user = database.getUserById(userId);

            if (user == null || user.isDeleted() || user.isDeactivated()) {
                logger.warn("User not found or deactivated: {userId: " + userId + "}");
                return 0;
            }

            LocalDate thirtyDaysAgo = LocalDate.now().minus(30, ChronoUnit.DAYS);
            logger.debug("Fetching posts for user since: {userId: " + userId + ", 
                    since: " + thirtyDaysAgo + "}");
            List<Post> posts = database.getPostsByUserSince(user, thirtyDaysAgo);

            int totalLikes = 0;
            for (Post post : posts) {
                totalLikes += post.getLikes().size();
            }

            long endTime = System.nanoTime();
            // compute the elapsed time in nanoseconds
            long duration = (endTime - startTime);  
            logger.info("Execution time: {timeInNanoseconds: " + duration + "}");
            logger.info("Returning total likes in last 30 days for: {userId: " + 
                    userId + ", totalLikes: " + totalLikes + "}");

            return totalLikes;
        } catch (Exception e) {
            logger.error("An error occurred: {message: " + e.getMessage() + "}", e);
            return 0;
        }
    }
}



So könnten die Protokolle im Erfolgsfall aussehen:


2024-01-07 14:00:00,001 [INFO]  UserService.java:10 [com.example.UserService] (getTotalLikesInLast30Days) : Request received to get all total likes in last 30 days for: {userId: 123}
2024-01-07 14:00:00,002 [DEBUG] UserService.java:12 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching user with id: {userId: 123}
2024-01-07 14:00:00,010 [DEBUG] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching posts for user since: {userId: 123, since: 2023-12-08}
2024-01-07 14:00:00,020 [INFO]  UserService.java:26 [com.example.UserService] (getTotalLikesInLast30Days) : Execution time: {timeInNanoseconds: 19000000}
2024-01-07 14:00:00,021 [INFO]  UserService.java:28 [com.example.UserService] (getTotalLikesInLast30Days) : Returning total likes in last 30 days for: {userId: 123, totalLikes: 999}


Und so könnten sie aussehen, wenn eine Ausnahme auftritt, beispielsweise wenn die Post-Tabelle nicht vorhanden ist:


2024-01-07 14:00:00,001 [INFO]  UserService.java:10 [com.example.UserService] (getTotalLikesInLast30Days) : Request received to get all total likes in last 30 days for: {userId: 123}
2024-01-07 14:00:00,002 [DEBUG] UserService.java:12 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching user with id: {userId: 123}
2024-01-07 14:00:00,010 [DEBUG] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching posts for user since: {userId: 123, since: 2023-12-08}
2024-01-07 14:00:00,015 [ERROR] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : An error occurred: {message: "Post table does not exist"}


Packages like log4j, slf4j, and many others can be used for better management of logs in large software programs.

Focusing on creating effective logs for each function can significantly improve the overall quality of logs for the entire software. This approach ensures that each part of the software is well-documented and can facilitate easier debugging and maintenance. Remember, a well-logged function contributes to a well-logged application.

Thank you for reading this blog. _Sayonara!

Das obige ist der detaillierte Inhalt vonEffektive Protokollierung für die Funktion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn