JavaRush /จาวาบล็อก /Random-TH /การบันทึก Java ผ่อนคลายลูกบอลสเตกเทรซ

การบันทึก Java ผ่อนคลายลูกบอลสเตกเทรซ

เผยแพร่ในกลุ่ม
“สวัสดีตอนบ่าย วันนี้มีการบันทึกเหตุการณ์ที่ไซต์อุตสาหกรรม ฉันขอให้นักพัฒนาเข้าร่วมกลุ่มวิเคราะห์” วันหนึ่งในที่ทำงานของคุณอาจเริ่มต้นอะไรแบบนี้ หรืออาจเป็นตอนเช้า ไม่สำคัญหรอก แต่ขอเริ่มต้นจากจุดเริ่มต้น ด้วยการแก้ปัญหาที่นี่ใน JavaRush คุณจะได้เรียนรู้การเขียนโค้ดที่ใช้งานได้และทำสิ่งที่คาดหวังได้ หากคุณดูที่ ส่วน ช่วยเหลือเห็นได้ชัดว่าสิ่งนี้ไม่ได้ผลในครั้งแรกเสมอไป มันจะเหมือนกันในที่ทำงาน คุณไม่สามารถแก้ไขปัญหาได้ในครั้งแรกเสมอไป แมลงคือเพื่อนนิรันดร์ของเรา สิ่งสำคัญคือคุณสามารถกู้คืนเหตุการณ์ของจุดบกพร่องได้ การบันทึก  ผ่อนคลายลูกบอลสเตกเทรซ - 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 นกพิราบก็สะบัดตัวหนีออกไป
คุณไม่จำเป็นต้องเจาะลึกรายละเอียดดังกล่าวเป็นเวลานาน มันชัดเจนทันทีว่าเกิดอะไรขึ้น เช่นเดียวกับการพัฒนา มันเจ๋งมากเมื่อคุณสามารถบอกได้จากการบันทึกว่าเกิดอะไรขึ้น ตอนนี้คุณอาจจำการดีบักได้ เพราะคุณสามารถดีบั๊กได้ทุกอย่าง แต่ไม่มี. คุณกลับบ้านและในตอนกลางคืนทุกอย่างก็พังไม่มีอะไรต้องแก้ไข: คุณต้องเข้าใจว่าทำไมมันถึงพังและซ่อมมัน นี่คือจุดที่บันทึกเข้ามามีบทบาท ประวัติศาสตร์ของทุกสิ่งที่เกิดขึ้นในชั่วข้ามคืน ในระหว่างบทความ ผมขอแนะนำให้คุณลองนึกถึงหนึ่งในคนตัดไม้ที่มีชื่อเสียงที่สุด (ไม่ใช่คนตัดไม้จริงๆ แต่เป็นพวกเฝ้าติดตามมากกว่า) ซึ่งใครก็ตามที่ฟัง (ดู) ข่าวคงเคยได้ยินชื่อมาบ้าง ต้องขอบคุณเขาที่ทำให้เหตุการณ์บางอย่างได้รับการฟื้นฟู ตอนนี้เรามาจริงจังกัน การบันทึกใน Java เป็นกระบวนการบันทึกเหตุการณ์ใดๆ ที่เกิดขึ้นในโค้ด เป็นความรับผิดชอบของคุณในฐานะโปรแกรมเมอร์ที่จะต้องจดบันทึกสิ่งที่โค้ดของคุณทำ เพราะหลังจากนั้นระบบจะมอบบันทึกเหล่านี้ให้คุณเพื่อการวิเคราะห์ หากทุกอย่างทำได้ดี ข้อบกพร่องต่างๆ จะถูกแก้ไขและแก้ไขอย่างรวดเร็ว ที่นี่ฉันอาจจะไม่เจาะลึกว่ามีคนตัดไม้ประเภทใดบ้าง ในบทความนี้เราจะจำกัดตัวเองอยู่แค่เรื่องง่ายๆjava.util.Loggerแค่ทำความรู้จักกันก็เกินพอแล้ว แต่ละรายการบันทึกประกอบด้วยวันที่-เวลา ระดับเหตุการณ์ ข้อความ วันที่และเวลาจะถูกป้อนโดยอัตโนมัติ ผู้เขียนข้อความเป็นผู้เลือกระดับเหตุการณ์ มีหลายระดับ สิ่งสำคัญคือข้อมูล การแก้ไขข้อบกพร่อง ข้อผิดพลาด
  • ข้อมูล - โดยปกติจะเป็นข้อความข้อมูลเกี่ยวกับสิ่งที่เกิดขึ้น เช่น ประวัติศาสตร์ตามวันที่: 1915 - มีบางอย่างเกิดขึ้น 1916 - อย่างอื่น
  • DEBUG - อธิบายเหตุการณ์ในช่วงเวลาหนึ่งโดยละเอียดยิ่งขึ้น ตัวอย่างเช่น รายละเอียดของการต่อสู้ในประวัติศาสตร์อยู่ในระดับแก้ไขข้อบกพร่อง" ผู้บัญชาการ Takoytovich ก้าวมาพร้อมกับกองทัพของเขาไปยังหมู่บ้าน Selovicha "
  • ข้อผิดพลาด - ข้อผิดพลาดที่เกิดขึ้นมักจะเขียนไว้ที่นี่ คุณอาจสังเกตเห็นว่าเมื่อคุณห่ออะไรบางอย่างเข้าไปtry-catchบล็อกcatchจะถูกแทนที่ด้วยe.printStacktrace(). มันจะส่งออกรายการไปยังคอนโซลเท่านั้น เมื่อใช้คนตัดไม้ คุณสามารถส่งรายการนี้ไปยังคนตัดไม้ได้ (ฮ่าๆ) คุณก็เข้าใจแนวคิดนี้แล้ว
  • คำเตือน - มีการเขียนคำเตือนไว้ที่นี่ เช่น ไฟที่ร้อนเกินไปในรถยนต์ นี่เป็นเพียงคำเตือนและเป็นการดีกว่าที่จะเปลี่ยนแปลงบางสิ่ง แต่นี่ยังไม่พัง เมื่อเครื่องเสียเราจะบันทึกระดับ ERROR
เราได้เรียงลำดับระดับแล้ว แต่อย่ากังวล เส้นแบ่งระหว่างสิ่งเหล่านี้บางมาก ไม่ใช่ทุกคนที่จะอธิบายได้ นอกจากนี้ยังอาจแตกต่างกันไปในแต่ละโครงการ นักพัฒนาอาวุโสจะอธิบายให้คุณทราบถึงระดับใดและสิ่งที่ต้องบันทึก สิ่งสำคัญคือบันทึกเหล่านี้เพียงพอสำหรับคุณสำหรับการวิเคราะห์ในอนาคต และนี่คือสิ่งที่เข้าใจได้ทันที ถัดไปคือการตั้งค่า Loggers สามารถบอกตำแหน่งที่จะเขียนได้ (ไปยังคอนโซล, ไฟล์, 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
ในกรณีนี้ ทุกอย่างได้รับการกำหนดค่าเพื่อให้คนบันทึกเขียนลงในไฟล์และคอนโซลในเวลาเดียวกัน ในกรณีนั้น? หากมีบางสิ่งถูกลบในคอนโซล นอกจากนี้ยังง่ายต่อการค้นหาด้วยไฟล์ ระดับข้อมูลสำหรับทั้งสอง มีการระบุรูปแบบชื่อสำหรับไฟล์ด้วย นี่เป็นการกำหนดค่าขั้นต่ำที่ช่วยให้คุณสามารถเขียนทั้งคอนโซลและไฟล์ได้ในคราวเดียว java.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... ข้อเสียประการหนึ่งปรากฏที่นี่แล้ว: 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