JavaRush /Java Blog /Random-JA /Java ログ。stectrace のボールをほどく

Java ログ。stectrace のボールをほどく

Random-JA グループに公開済み
「こんにちは。今日、産業現場でインシデントが記録されました。開発者に分析グループへの参加をお願いします。」 一日の仕事の中でこのようなことが始まるかもしれませんし、朝かもしれませんが、それは問題ではありません。しかし、最初から始めましょう。JavaRush で問題を解決することで、期待どおりに動作するコードの書き方を学びます。ヘルプセクションを見ると、これが最初からうまくいかないことは明らかです。それは仕事でも同じだろう。問題は最初から解決できるとは限りません。バグは私たちの永遠の仲間です。バグのイベントを復元できることが重要です。 ロギング。 stectrace のボールを解く - 1例から始めましょう。あなたが警察官であると想像してみましょう。あなたは事件現場(店内のガラスが割れた)に呼ばれ、到着し、何が起こったのかについてあなたからの回答を待っています。どこから始めればよいでしょうか?警察がどのように動いているのか分かりません。非常に条件付きで、彼らは証人、証拠、その他すべてのものを探し始めます。その場所自体が何が起こったのかを詳しく教えてくれたらどうでしょうか?たとえば、次のようになります。
  • 21:59 オーナーがアラームをオンにしました(完全に作動するまで 5 分)
  • 22:00 オーナーがドアを閉めた
  • 22:05 アラーム完全作動
  • 22:06 オーナーがハンドルを引いた
  • 23:15 ノイズセンサーがオンになりました
  • 23:15 犬の群れが大声で吠えながら走り去った
  • 23:15 騒音センサーがオフになりました
  • 01:17 ショーケース外側ガラスの衝撃センサーが作動
  • 01:17 ハトがガラスに飛び込みました
  • 01:17 ガラスが割れた
  • 01:17 サイレンが鳴る
  • 01:17 ハトは身を振り払って飛び去った
まあ、そのような詳細を長く掘り下げる必要はありません。何が起こったのかはすぐに明らかです。同じように開発中です。何が起こったかを録音から知ることができるのはとても素晴らしいことです。すべてをデバッグできるため、デバッグのことを思い出したかもしれません。しかし、そうではありません。家に帰って、夜にすべてが壊れました。デバッグするものは何もありません。なぜ壊れたのかを理解し、修正する必要があります。ここでログが活躍し、一晩に起こったすべての履歴が記録されます。この記事の途中で、ニュースを聞いている (見ている) 人なら誰もが聞いたことがあるであろう、最も有名なロガー (実際にはロガーではなく、モニタリングに近いもの) の 1 つについて考えてみることをお勧めします。彼のおかげでいくつかのイベントが復活しました。さあ、真剣にいきましょう。Java へのログインは、コード内で発生したイベントを記録するプロセスです。コードが何を行ったかを書き留めるのはプログラマとしての責任です。そうすれば、これらのログは分析のために提供されるからです。すべてがうまくいけば、バグはすぐに解決され、修正されます。ここでは、ロガーの種類については詳しく説明しません。java.util.Loggerこの記事では、お互いを知るには十分すぎるほど簡単な内容に限定します。各ログ エントリには、日時、イベント レベル、メッセージが含まれます。日付と時刻は自動的に入力されます。イベント レベルはメッセージ作成者によって選択されます。いくつかのレベルがあります。主なものは情報、デバッグ、エラーです。
  • INFO - 通常、これらは何が起こっているかに関する情報メッセージで、日付ごとの履歴のようなものです。1915 年 - 何かが起こった、1916 年 - 何か他の出来事。
  • DEBUG - 特定の瞬間のイベントをより詳細に説明します。たとえば、歴史上の戦闘の詳細はデバッグ レベルです。「タコイトビッチ司令官は軍隊とともにセロヴィチャ村に向かって前進しました。」
  • エラー - 発生したエラーは通常ここに書き込まれます。おそらく、何かを で囲むとtry-catch、ブロックがcatchで置き換えられることに気づいたでしょうe.printStacktrace()。エントリをコンソールに出力するだけです。ロガーを使用すると、このエントリをロガーに送信できます (笑)、アイデアはわかりますか。
  • 警告 - 警告はここに書かれます。たとえば、車のオーバーヒートライトなどです。これは単なる警告であり、何かを変更した方が良いですが、これは故障ではありません。マシンが故障すると、ERROR レベルでログが記録されます。
レベルを整理しました。しかし、心配しないでください。両者の間の境界線は非常に薄く、誰もがそれを説明できるわけではありません。さらに、プロジェクトごとに異なる場合があります。上級開発者が、どのレベルで何をログに記録するかを説明します。重要なことは、これらの記録が将来の分析に十分であるということです。そしてこれはその場で理解されます。次に設定です。ロガーには、書き込む場所 (コンソール、ファイル、jms、またはその他の場所) を指示し、レベル (情報、エラー、デバッグなど) を指定できます。 単純なロガーの設定例は次のようになります。
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler

java.util.logging.FileHandler.level     = INFO
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append    = true
java.util.logging.FileHandler.pattern   = log.%u.%g.txt

java.util.logging.ConsoleHandler.level     = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
この場合、ロガーがファイルとコンソールに同時に書き込むようにすべてが構成されています。その場合は?コンソールで何かが消去された場合に加えて、ファイルによる検索が簡単になります。どちらも INFO レベル。ファイルの名前パターンも指定されます。これは、コンソールとファイルの両方に一度に書き込むことができる最小限の構成です。 ファイル内の古いエントリが消去されないようにtruejava.util.logging.FileHandler.appendに設定します。使用例は次のとおりです (コメントなしでは、ロガー自体がコメントします)。
public class Main {
    static Logger LOGGER;
    static {
        try(FileInputStream ins = new FileInputStream("C:\\log.config")){ \\полный путь до file с конфигами
            LogManager.getLogManager().readConfiguration(ins);
            LOGGER = Logger.getLogger(Main.class.getName());
        }catch (Exception ignore){
            ignore.printStackTrace();
        }
    }
    public static void main(String[] args) {
        try {
            LOGGER.log(Level.INFO,"Начало main, создаем лист с типизацией Integers");
            List<Integer> ints = new ArrayList<Integer>();
            LOGGER.log(Level.INFO,"присваиваем лист Integers листу без типипзации");
            List empty = ints;
            LOGGER.log(Level.INFO,"присваиваем лист без типипзации листу строк");
            List<String> string = empty;
            LOGGER.log(Level.WARNING,"добавляем строку \"бла бла\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла бла");
            LOGGER.log(Level.WARNING,"добавляем строку \"бла 23\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла 23");
            LOGGER.log(Level.WARNING,"добавляем строку \"бла 34\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла 34");


            LOGGER.log(Level.INFO,"выводим все элементы листа с типизацией Integers в консоль");
            for (Object anInt : ints) {
                System.out.println(anInt);
            }

            LOGGER.log(Level.INFO,"Размер equals " + ints.size());
            LOGGER.log(Level.INFO,"Получим первый элемент");
            Integer integer = ints.get(0);
            LOGGER.log(Level.INFO,"выведем его в консоль");
            System.out.println(integer);

        }catch (Exception e){
            LOGGER.log(Level.WARNING,"что-то пошло не так" , e);
        }
    }
}
これは最良の例ではありません。私は手元にあったものを取り上げました。出力例:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Начало main, создаем лист с типизацией Integers
апр 19, 2019 1:10:14 AM generics.Main main
INFO: присваиваем лист Integers листу без типипзации
апр 19, 2019 1:10:14 AM generics.Main main
INFO: присваиваем лист без типипзации листу строк
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла бла" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла 23" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла 34" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
INFO: выводим все элементы листа с типизацией Integers в консоль
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: что-то пошло не так
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
	at generics.Main.main(Main.java:45)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
ここではメモに焦点を当てたいと思います。
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
このエントリはまったく役に立たず、有益ではありません。エラーエントリのように:
WARNING: что-то пошло не так
これは書かないでください。これはログのためのログであり、邪魔になるだけです。常に意味のあることを書くようにしてください。System.out.printlnこれは使用をやめて大人のおもちゃに移行する のに十分だと思います。デメリットもありますjava.util.logging。たとえば、上で説明したレベルはここにはありませんが、ほとんどの使用されているロガーには含まれています。この記事では、java.util.logging接続に追加の操作を必要としないため、これを選択しました。LOGGER.infoまた、代わりに使用できることにも注意してくださいLOGGER.log(Level.INFO... 。欠点の 1 つは、ここですでに示しています。 LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- メッセージとオブジェクトを送信できますExceptionが、ロガー自体がそれを美しく記録します。同時に、LOGGER.warning("");メッセージのみを受信します。例外は渡すことができないため、自分で文字列に変換する必要があります。この例が Java ロギングについて理解するには十分だと思います。次に、他のロガー (log4j、slf4j、Logback...) を接続できます。たくさんありますが、本質は同じで、アクションの履歴を記録します。 公式チュートリアル
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION