ホームページ  >  記事  >  Java  >  機能の効果的なロギング

機能の効果的なロギング

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-05 14:08:021033ブラウズ

Effective Logging for Function

関数レベルのロギングをマスターすることは、ソフトウェア システム全体の包括的なロギングを理解して実装するための重要なステップです。機能の粒度レベルに焦点を当てることで、複雑なシステムへのスケールアップを容易にする強固な基盤を構築できます。

関数のログを作成する際に覚えておくべき 5 つの重要なポイントを次に示します。

  1. ログの発行元を指定します:

    • ログのソースを必ず書き留めてください。これには、ファイルの作成時間、ファイル名、関連する機能、その他多くの詳細が含まれます。これは、開発者が特定のファイルまたは機能に集中できるため、トラブルシューティングの際に役立ちます。
  2. デバッグを念頭に置いて書く:

    • ログを書き込むときは、発生する可能性のある潜在的な問題を考慮してください。ログは、これらの問題が発生した場合にその解決に役立つ方法で書き込まれる必要があります。
  3. ストーリーをナレーションする:

    • ログは、要点に沿った、重要な詳細をすべて網羅したストーリーのようなものである必要があります。各関数には、受け取った引数で始まり、返されたデータで終わる独自の説明が必要です。ログには、実行時間、呼び出した内部関数、受け取った入力、返された出力が含まれます。
  4. ログを徹底的にテストします:

    • 完了後のテスト機能と同様に、ログもテストする必要があります。成功した場合と失敗した場合の両方について、ログに正しい情報が表示されていることを確認します。常に、問題を解決しようとしている人の視点からログを表示してください。
  5. 過剰なログを避ける:

    • すべてをログに記録する必要はありません。機密情報、特にユーザーデータに関する場合は省略する必要があります。たとえば、すべてのユーザーの詳細をログに記録するのではなく、ユーザーの ID またはコードで利用された情報のみをログに記録する必要があります。

正しいレベルでログを記録することを忘れないでください。

  • 情報 - アプリの操作に関する機密ではない詳細をログに記録します。
  • 警告 - ユーザー エクスペリエンスに影響を与えることなく、潜在的な問題にフラグを立てます。
  • エラー - ユーザー エクスペリエンスに影響を与える重大な問題を示します。
  • 致命的 - ユーザー エクスペリエンスに重大な影響を与える重大なエラーを示します。
  • DEBUG - 開発者にデバッグ情報を提供します。

関数ログのベスト プラクティス

ログ文字列内の必須要素: TimestampApplicationNameFileNameFunctionName の組み込み、LEVEL、およびその他の関連詳細により、アプリケーションのログの有効性が大幅に向上します。これらの要素は重要なコンテキストを提供し、特にアプリケーションのデバッグや監視時にイベント フローを追跡しやすくします。目標は、プライバシーとセキュリティの考慮事項を尊重しながら、有益で役立つログを作成することであることを忘れないでください。

メッセージは以下を伝える必要があります: 意図されたアクション、アクションの開始者、入力と出力。

次の非構造化ログ エントリについて考えてみましょう:


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


これらのエントリを JSON として構造化することで、読みやすさと解析の容易さが向上します。


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}


これらの慣行に従うことで、ログが有益で読みやすく、デバッグに役立つものになることが保証されます。

コード例とベストプラクティス

  • ログの一貫性と均一性を維持する: コードを作成する開発者の数に関係なく、プログラム全体でログの一貫性を確保することが重要です。これにより、デバッグが容易になり、操作の流れを理解し、コード実行の追跡可能性が向上します。
  • ログ テンプレートを作成し、同じログ パターンを使用する: チーム全体用の標準ログ テンプレートを開発し、チーム内のすべての開発者が同じログ パターンに従うことを奨励します。これにより均一性が高まり、ログが読みやすくなり、理解しやすくなります。
  • サンプル関数の提供と参照: コード内で適切なロギング方法を示すサンプル関数をいくつか用意します。これらは開発者にとっての参考として役立ちます。開発者が独自のコードを作成するときにこれらの例を参照できるようにします。これにより、確立されたログ記録慣行を遵守し、一貫性を維持することができます。

これが例です:


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;
        }
    }
}



成功した場合のログは次のようになります:


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}


Post テーブルが存在しない場合など、例外が発生した場合は次のようになります。


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!

以上が機能の効果的なロギングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。