JavaRush /Blog Java /Random-VI /Ghi nhật ký Java. Thư giãn một quả bóng stectrace

Ghi nhật ký Java. Thư giãn một quả bóng stectrace

Xuất bản trong nhóm
"Chào buổi chiều, hôm nay khu công nghiệp được ghi nhận một sự cố, tôi yêu cầu chủ đầu tư tham gia nhóm phân tích." Một ngày làm việc của bạn có thể bắt đầu như thế này, hoặc có thể là buổi sáng - điều đó không thành vấn đề. Nhưng hãy bắt đầu lại từ đầu. Bằng cách giải quyết các vấn đề ở đây trong JavaRush, bạn học cách viết mã hoạt động và thực hiện những gì được mong đợi. Nếu bạn nhìn vào phần trợ giúp , có thể thấy rõ rằng điều này không phải lúc nào cũng diễn ra ngay lần đầu tiên. Nó sẽ giống nhau ở nơi làm việc. Không phải lúc nào bạn cũng giải quyết được vấn đề ngay lần đầu tiên: lỗi là người bạn đồng hành vĩnh cửu của chúng ta. Điều quan trọng là bạn có thể khôi phục các sự kiện xảy ra lỗi. Ghi nhật ký.  Thư giãn một quả bóng stectrace - 1Hãy bắt đầu với một ví dụ. Hãy tưởng tượng bạn là một cảnh sát. Bạn được gọi đến hiện trường vụ việc (kính bị vỡ trong một cửa hàng), bạn đã đến nơi và họ đang chờ câu trả lời từ bạn về những gì đã xảy ra. Nơi để bắt đầu? Tôi không biết cảnh sát làm việc thế nào. Rất có điều kiện - họ bắt đầu tìm kiếm nhân chứng, bằng chứng và tất cả những thứ đó. Điều gì sẽ xảy ra nếu chính nơi đó có thể cho bạn biết chi tiết chuyện gì đã xảy ra? Ví dụ như thế này:
  • 21:59 chủ sở hữu bật báo thức (5 phút cho đến khi kích hoạt hoàn toàn)
  • 22h chủ nhà đóng cửa lại
  • 22:05 kích hoạt báo động đầy đủ
  • 22:06 chủ nhà rút tay cầm
  • 23:15 bật cảm biến tiếng ồn
  • 23:15 có đàn chó chạy qua sủa ầm ĩ
  • 23:15 cảm biến tiếng ồn đã tắt
  • 01:17 cảm biến sốc trên kính ngoài của hộp trưng bày được bật
  • 01:17 một con chim bồ câu bay vào kính
  • 01:17 kính bị vỡ
  • 01:17 còi báo động bật
  • 01:17 con chim bồ câu rũ mình và bay đi
Chà, bạn không cần phải đi sâu vào những chi tiết như vậy lâu, bạn sẽ hiểu ngay chuyện gì đã xảy ra. Điều tương tự cũng xảy ra trong quá trình phát triển. Thật tuyệt khi bạn có thể biết được điều gì đã xảy ra từ đoạn ghi âm. Bây giờ bạn có thể đang nhớ việc gỡ lỗi vì bạn có thể gỡ lỗi mọi thứ. Nhưng không. Bạn về nhà, đến đêm mọi thứ đều hỏng, không có gì phải sửa: bạn cần hiểu tại sao nó hỏng và sửa nó. Đây là nơi các nhật ký phát huy tác dụng, lịch sử của mọi thứ xảy ra chỉ sau một đêm. Trong quá trình viết bài, tôi khuyên bạn nên nghĩ xem đâu là một trong những công cụ ghi nhật ký nổi tiếng nhất (không hẳn là một công cụ ghi nhật ký, giống như giám sát hơn), mà tất cả những ai nghe (xem) tin tức có thể đã nghe nói đến? Nhờ có anh ấy, một số sự kiện được khôi phục. Bây giờ chúng ta hãy nghiêm túc. Đăng nhập Java là quá trình ghi lại bất kỳ sự kiện nào xảy ra trong mã. Với tư cách là một lập trình viên, bạn có trách nhiệm viết ra những gì mã của bạn đã làm, bởi vì sau đó những nhật ký này sẽ được cung cấp cho bạn để phân tích. Nếu mọi thứ được thực hiện tốt thì mọi lỗi sẽ được sắp xếp và sửa chữa rất nhanh chóng. Ở đây, có lẽ tôi sẽ không đi sâu tìm hiểu xem có những loại máy ghi nhật ký nào. Trong bài viết này, chúng tôi sẽ giới hạn ở mức độ đơn giản java.util.Logger: chỉ cần tìm hiểu nhau là quá đủ. Mỗi mục nhật ký chứa ngày giờ, cấp độ sự kiện, thông báo. Ngày và giờ được nhập tự động. Mức độ sự kiện được lựa chọn bởi tác giả tin nhắn. Có một số cấp độ. Những cái chính là thông tin, gỡ lỗi, lỗi.
  • THÔNG TIN - thông thường đây là những thông báo thông tin về những gì đang xảy ra, giống như lịch sử theo ngày tháng: 1915 - điều gì đó đã xảy ra, 1916 - điều gì đó khác.
  • GỠ LỖI - mô tả các sự kiện của một thời điểm cụ thể chi tiết hơn. Ví dụ, các chi tiết của một trận chiến trong lịch sử đều ở mức gỡ lỗi. " Chỉ huy Takoytovich cùng quân đội của mình tiến về làng Selovicha ."
  • LỖI - lỗi xảy ra thường được viết ở đây. Có thể bạn đã nhận thấy rằng khi bạn bọc thứ gì đó vào trong try-catch, khối đó catchđược thay thế bằng e.printStacktrace(). Nó chỉ xuất mục nhập vào bàn điều khiển. Sử dụng một trình ghi nhật ký, bạn có thể gửi mục này đến trình ghi nhật ký (haha), bạn hiểu ý rồi đấy.
  • CẢNH BÁO - cảnh báo được viết ở đây. Ví dụ, đèn quá nóng trong ô tô. Đây chỉ là một lời cảnh báo và tốt hơn là bạn nên thay đổi điều gì đó, nhưng đây không phải là sự cố. Khi máy bị hỏng thì chúng ta sẽ log với mức LỖI.
Chúng tôi đã sắp xếp các cấp độ. Nhưng đừng lo lắng: ranh giới giữa chúng rất mong manh - không phải ai cũng có thể giải thích được. Thêm vào đó, nó có thể khác nhau tùy theo từng dự án. Nhà phát triển cấp cao sẽ giải thích cho bạn ở cấp độ nào và nội dung nào cần ghi lại. Điều chính là những hồ sơ này là đủ để bạn phân tích trong tương lai. Và điều này được hiểu một cách nhanh chóng. Tiếp theo là các cài đặt. Trình ghi nhật ký có thể được cho biết nơi ghi (vào bảng điều khiển, tệp, jms hoặc nơi nào khác) và chỉ định mức độ (thông tin, lỗi, gỡ lỗi...). Một ví dụ về cài đặt cho trình ghi nhật ký đơn giản của chúng tôi trông như thế này:
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
Trong trường hợp này, mọi thứ đều được cấu hình để trình ghi nhật ký ghi vào một tệp và vào bảng điều khiển cùng một lúc. Trong trường hợp đó? nếu nội dung nào đó bị xóa trong bảng điều khiển, đồng thời việc tìm kiếm theo tệp sẽ dễ dàng hơn. Mức độ INFO cho cả hai. Mẫu tên cũng được chỉ định cho tệp. Đây là cấu hình tối thiểu cho phép bạn ghi vào cả bảng điều khiển và tệp cùng một lúc. java.util.logging.FileHandler.appendđược đặt thành true để các mục cũ trong tệp không bị xóa. Một ví dụ về việc sử dụng là thế này (không có nhận xét, trình ghi nhật ký sẽ tự nhận xét):
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);
        }
    }
}
Đây không phải là ví dụ tốt nhất, tôi đã lấy ví dụ có trong tay. Đầu ra ví dụ:
апр 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)
Ở đây tôi muốn tập trung vào các ghi chú:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
Mục này khá vô ích và không có nhiều thông tin. Giống như mục nhập lỗi:
WARNING: что-то пошло не так
Bạn không nên viết điều này: đó là nhật ký chỉ vì nhật ký, nó sẽ chỉ gây cản trở mà thôi. Hãy cố gắng luôn viết những điều có ý nghĩa. Tôi nghĩ thế là đủ để ngừng sử dụng System.out.printlnvà chuyển sang đồ chơi người lớn. Nó java.util.loggingcó nhược điểm. Ví dụ: các cấp độ mà tôi mô tả ở trên không có ở đây nhưng chúng có trong hầu hết các trình ghi nhật ký được sử dụng nhiều nhất. Tôi chọn nó cho bài viết này java.util.loggingvì nó không yêu cầu các thao tác bổ sung với kết nối. Tôi cũng sẽ lưu ý rằng nó có thể được sử dụng LOGGER.infothay thế. LOGGER.log(Level.INFO... Một trong những nhược điểm đã xuất hiện ở đây: LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- nó cho phép bạn truyền một tin nhắn và một đối tượng Exception, bản thân trình ghi nhật ký sẽ ghi nó xuống rất đẹp. Đồng thời, LOGGER.warning("");nó chỉ nhận được một tin nhắn, tức là. Ngoại lệ không thể được thông qua, bạn phải tự dịch nó thành một chuỗi. Tôi hy vọng ví dụ này đủ để bạn làm quen với việc ghi nhật ký Java. Sau đó, bạn có thể kết nối các trình ghi nhật ký khác (log4j, slf4j, Logback...) - có rất nhiều trình ghi nhật ký, nhưng bản chất là như nhau^ để ghi lại lịch sử các hành động. Hướng dẫn chính thức
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION