JavaRush /Java Blog /Random-TL /Pag-log sa Java. I-unwind ang isang bola ng stectrace

Pag-log sa Java. I-unwind ang isang bola ng stectrace

Nai-publish sa grupo
"Magandang hapon, ngayon ang isang insidente ay naitala sa pang-industriyang site, hinihiling ko sa developer na sumali sa grupo ng pagsusuri." Ang isa sa iyong mga araw sa trabaho ay maaaring magsimula ng isang bagay na tulad nito, o maaaring ito ay sa umaga - hindi ito mahalaga. Ngunit magsimula tayo sa simula. Sa pamamagitan ng paglutas ng mga problema dito sa JavaRush, natututo kang magsulat ng code na gumagana at ginagawa ang inaasahan dito. Kung titingnan mo ang seksyon ng tulong , malinaw na hindi ito palaging gagana sa unang pagkakataon. Magiging pareho din ito sa trabaho. Hindi mo palaging malulutas ang isang problema sa unang pagkakataon: ang mga bug ay ang aming walang hanggang mga kasama. Mahalagang maibalik mo ang mga kaganapan ng bug. Pagtotroso.  I-unwind ang bola ng stectrace - 1Magsimula tayo sa isang halimbawa. Isipin natin na isa kang pulis. Pinatawag ka sa pinangyarihan ng insidente (basag ang salamin sa isang tindahan), dumating ka, at naghihintay sila ng mga sagot mula sa iyo tungkol sa nangyari. Saan magsisimula? Hindi ko alam kung paano gumagana ang mga pulis. Napakakondisyon - nagsimula silang maghanap ng mga saksi, ebidensya at lahat ng bagay na iyon. Paano kung ang lugar mismo ay makapagsasabi sa iyo nang detalyado kung ano ang nangyari? Halimbawa, tulad nito:
  • 21:59 binuksan ng may-ari ang alarma (5 minuto hanggang ganap na ma-activate)
  • 22:00 isinara ng may-ari ang pinto
  • 22:05 full alarm activation
  • 22:06 hinila ng may-ari ang hawakan
  • Naka-on ang 23:15 noise sensor
  • 23:15 tumakbo ang isang pakete ng mga aso, tumatahol ng malakas
  • Naka-off ang 23:15 noise sensor
  • 01:17 naka-on ang shock sensor sa panlabas na salamin ng display case
  • 01:17 lumipad ang isang kalapati sa salamin
  • 01:17 nabasag ang salamin
  • 01:17 nakabukas ang sirena
  • 01:17 umiling ang kalapati at lumipad palayo
Buweno, hindi mo kailangang pag-aralan nang matagal ang mga naturang detalye; malinaw na kaagad kung ano ang nangyari. Ganun din sa development. Napaka-cool kapag nasasabi mo mula sa mga pag-record kung ano ang nangyari. Ngayon ay maaaring naaalala mo ang pag-debug, dahil maaari mong i-debug ang lahat. Pero hindi. Umuwi ka, at sa gabi nasira ang lahat, walang dapat i-debug: kailangan mong maunawaan kung bakit ito nasira at ayusin ito. Dito pumapasok ang mga log, ang kasaysayan ng lahat ng nangyari sa magdamag. Sa panahon ng artikulo, iminumungkahi kong isipin mo kung ano ang isa sa mga pinakasikat na logger (hindi talaga isang logger, mas katulad ng pagsubaybay), na malamang na narinig ng lahat ng nakikinig (nanunuod) ng balita? Salamat sa kanya, naibalik ang ilang mga kaganapan. Ngayon magseryoso tayo. Ang pag-log in sa Java ay ang proseso ng pagtatala ng anumang mga kaganapan na nangyayari sa code. Responsibilidad mo bilang isang programmer na isulat kung ano ang ginawa ng iyong code, dahil ang mga log na ito ay ibibigay sa iyo para sa pagsusuri. Kung maayos ang lahat, ang anumang bug ay aayusin at aayusin nang napakabilis. Dito, hindi ko na siguro sisilipin kung anong klaseng logger ang meron. Sa artikulong ito ay lilimitahan natin ang ating sarili sa simple java.util.Logger: ito ay higit pa sa sapat para makilala ang isa't isa. Ang bawat log entry ay naglalaman ng petsa-oras, antas ng kaganapan, mensahe. Awtomatikong ipinapasok ang petsa at oras. Ang antas ng kaganapan ay pinili ng may-akda ng mensahe. Mayroong ilang mga antas. Ang mga pangunahing ay impormasyon, debug, error.
  • INFO - kadalasan ito ay mga mensahe ng impormasyon tungkol sa kung ano ang nangyayari, tulad ng isang kasaysayan ayon sa petsa: 1915 - may nangyari, 1916 - iba pa.
  • DEBUG - inilalarawan ang mga kaganapan ng isang partikular na sandali nang mas detalyado. Halimbawa, ang mga detalye ng isang labanan sa kasaysayan ay nasa antas ng debug." Si Commander Takoytovich ay sumulong kasama ang kanyang hukbo patungo sa nayon ng Selovicha ."
  • ERROR - ang mga error na nangyayari ay karaniwang nakasulat dito. Marahil ay napansin mo na kapag binalot mo ang isang bagay sa try-catch, ang bloke catchay pinapalitan ng e.printStacktrace(). Inilalabas lamang nito ang entry sa console. Gamit ang isang logger, maaari mong ipadala ang entry na ito sa logger (haha), nakuha mo ang ideya.
  • WARN - nakasulat dito ang mga babala. Halimbawa, isang overheating na ilaw sa isang kotse. Babala lamang ito, at mas mabuting baguhin ang isang bagay, ngunit hindi pa ito isang pagkasira. Kapag nasira ang makina, pagkatapos ay mag-log kami sa antas ng ERROR.
Inayos namin ang mga antas. Ngunit huwag mag-alala: ang linya sa pagitan nila ay napakanipis - hindi lahat ay maaaring ipaliwanag ito. Dagdag pa, maaari itong mag-iba sa bawat proyekto. Ipapaliwanag sa iyo ng isang senior developer kung anong antas at kung ano ang dapat i-log. Ang pangunahing bagay ay sapat na ang mga talang ito para sa iyo para sa pagsusuri sa hinaharap. At ito ay naiintindihan sa mabilisang. Susunod ay ang mga setting. Maaaring sabihin sa mga logger kung saan magsusulat (sa console, file, jms o sa ibang lugar), at tukuyin ang antas (impormasyon, error, debug...). Ang isang halimbawa ng mga setting para sa aming simpleng logger ay ganito ang hitsura:
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
Sa kasong ito, ang lahat ay na-configure upang ang logger ay sumulat sa isang file at sa console sa parehong oras. Sa kasong iyon? kung may nabubura sa console, at mas madaling maghanap sa pamamagitan ng file. INFO level para sa dalawa. Ang isang pattern ng pangalan ay tinukoy din para sa file. Ito ay isang minimal na config na nagbibigay-daan sa iyong sumulat sa parehong console at isang file nang sabay-sabay. java.util.logging.FileHandler.appenditakda sa true para hindi mabura ang mga lumang entry sa file. Ang isang halimbawa ng paggamit ay ito (nang walang mga komento, ang logger ay nagkomento sa sarili nito):
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);
        }
    }
}
Ito ay hindi ang pinakamahusay na halimbawa, kinuha ko ang isa na nasa kamay. Halimbawang output:
апр 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)
Dito gusto kong tumuon sa mga tala:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
Ang entry na ito ay medyo walang silbi at hindi nagbibigay-kaalaman. Tulad ng entry ng error:
WARNING: что-то пошло не так
Hindi mo dapat isulat ito: ito ay isang log para sa kapakanan ng isang log, ito ay makakasagabal lamang. Subukang laging magsulat ng mga makabuluhang bagay. Sa tingin ko ito ay sapat na upang ihinto ang paggamit nito System.out.printlnat magpatuloy sa mga laruang pang-adulto. Ito java.util.loggingay may mga disadvantages. Halimbawa, ang mga antas na inilarawan ko sa itaas ay wala dito, ngunit ang mga ito ay nasa karamihan ng mga ginagamit na logger. Pinili ko ito para sa artikulong ito java.util.loggingdahil hindi ito nangangailangan ng karagdagang pagmamanipula sa koneksyon. Mapapansin ko rin na maaari itong gamitin LOGGER.infosa halip na LOGGER.log(Level.INFO... Isa sa mga disadvantages ay lilitaw na dito: LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- pinapayagan ka nitong magpadala ng isang mensahe at isang bagay Exception, ang logger mismo ay isusulat ito nang maganda. Kasabay nito, LOGGER.warning("");nakakatanggap lamang ito ng isang mensahe, i.e. Ang pagbubukod ay hindi maaaring ipasa, kailangan mong isalin ito sa isang string mismo. Sana ay sapat na ang halimbawang ito upang maging pamilyar sa Java logging. Pagkatapos ay maaari mong ikonekta ang iba pang mga logger (log4j, slf4j, Logback...) - marami sa kanila, ngunit ang kakanyahan ay pareho^ upang itala ang kasaysayan ng mga aksyon. Opisyal na tutorial
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION