"Oh, andyan ka pala! Naalala mo ba may lesson pa tayo ngayon?"

"Hindi, hinanap lang kita. Halos..."

"Excellent, then let's start. Today I want to tell you about logging."

"Ang log ay isang listahan ng mga pangyayaring naganap. Halos parang log ng barko o talaarawan. O Twitter — siguro mas makakarelate ka doon. Hindi nakakagulat, ang logger ay isang bagay na ginagamit mo para sa pag-log."

"Sa programming, nakaugalian na mag-log halos lahat. At sa Java, ni-log namin ang lahat at kahit kaunti pa."

"Ang katotohanan ay ang mga Java program ay napakadalas na malalaking application ng server na walang UI, console, atbp. Pinoproseso nila ang libu-libong kahilingan ng user nang sabay-sabay, at madalas mayroong iba't ibang mga error. Lalo na kapag ang iba't ibang mga thread ay nagsimulang makagambala sa isa't isa."

"Sa katunayan, ang tanging paraan upang maghanap ng mga bihirang maaaring muling gawin na mga bug at pagkabigo sa mga sitwasyong ito ay ang pag-log sa lahat ng nangyayari sa bawat thread."

"Kadalasan, ang log ay naglalaman ng impormasyon tungkol sa mga argumento ng pamamaraan, anumang nahuli na mga error, at maraming intermediate na impormasyon."

"Kung mas kumpleto ang log, mas madaling magparami ng pagkakasunod-sunod ng mga kaganapan at subaybayan ang mga sanhi ng mga pagkabigo o mga bug."

"Minsan ang mga log ay umaabot ng ilang gigabytes bawat araw. Normal ito."

"Ilang gigabytes? O_o"

"Oo. Kadalasan, ang mga log file ay awtomatikong na-archive, na may indikasyon ng may-katuturang petsa."

"Whoa."

"Uh-huh. Noong una, walang sariling logger ang Java. Bilang resulta, maraming independiyenteng logger ang naisulat. Ang pinakakaraniwan sa mga ito ay log4j."

"Pagkalipas ng ilang taon, nakakuha ang Java ng sarili nitong logger, ngunit mas mababa ang functionality nito at hindi ito malawakang ginagamit."

"Ito ay isang katotohanan na ang Java ay may opisyal na logger, ngunit ang buong komunidad ng mga Java programmer ay mas gustong gumamit ng iba pang mga logger. "

"Mamaya, marami pang logger ang isinulat batay sa log4j."

"Kung gayon ang espesyal na unibersal na logger slf4j, na ngayon ay malawakang ginagamit, ay isinulat para sa kanilang lahat. Ito ay halos kapareho sa log4j, kaya gagamitin ko ito bilang isang halimbawa kapag nagpapaliwanag ng pag-log."

"Ang buong proseso ng pag-log ay binubuo ng tatlong bahagi."

" Una , mangolekta ng impormasyon."

" Pangalawa , salain ang mga nakolektang impormasyon."

" Pangatlo , itala ang napiling impormasyon."

"Magsimula tayo sa koleksyon. Narito ang isang tipikal na halimbawa ng isang klase na nag-log:"

Klase na may pag-log
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"Bigyang-pansin ang mga salitang naka-highlight sa pula."

" Linya 3  – Lumikha ng logger object. Ang ganitong static na object ay nilikha sa halos bawat klase! Well, maliban sa mga klase na walang ginagawa maliban sa pag-imbak ng data."

" Ang LoggerFactory ay isang espesyal na klase para sa paglikha ng mga logger, at ang getLogger ay isa sa mga static na pamamaraan nito. Ang kasalukuyang bagay ay karaniwang ipinapasa, ngunit ang iba't ibang mga opsyon ay posible."

" Linya 7 – Ang impormasyon tungkol sa tawag sa pamamaraan ay isinulat sa logger. Tandaan na ito ang unang linya ng pamamaraan. Sa sandaling tinawag ang pamamaraan, agad kaming nagsusulat ng impormasyon sa log."

"Tinatawag namin ang paraan ng pag-debug, na nangangahulugang ang kahalagahan ng impormasyon ay antas ng DEBUG. Ginagamit ito para sa pag-filter. Sasabihin ko sa iyo ang tungkol diyan sa loob ng ilang minuto."

" Linya 17 – Nakakuha kami ng eksepsiyon at... agad itong isulat sa talaan! Ito mismo ang kailangang gawin."

"Sa pagkakataong ito tinatawag namin ang paraan ng error, na agad na nagpapahiwatig na ang impormasyon ay antas ng ERROR"

Magtotroso - 1

"Mukhang malinaw na ang lahat sa ngayon. Well, as far as it can be clear in the middle of our conversation."

"Mahusay, pagkatapos ay lumipat tayo sa pag-filter ng mensahe."

"Karaniwan, ang bawat mensahe ng log ay may sariling antas ng kahalagahan, na maaari mong gamitin upang itapon ang ilan sa mga mensahe. Narito ang mga antas ng kahalagahan na binanggit ko:"

Antas ng kahalagahan Paglalarawan
LAHAT Lahat ng mensahe
TRACE Pinong mga mensahe sa pag-debug
DEBUG Mga mahahalagang mensahe sa pag-debug
IMPORMASYON Mga mensaheng nagbibigay-kaalaman
BALAAN Mga babala
ERROR Mga pagkakamali
FATAL Mga nakamamatay na pagkakamali
NAKA-OFF Walang mensahe

Ginagamit din ang mga antas na ito kapag nagpi-filter ng mga mensahe.

Ipagpalagay na itinakda mo ang antas ng pag-log sa WARN. Pagkatapos ang lahat ng mensaheng hindi gaanong mahalaga kaysa sa WARN ay itatapon: TRACE, DEBUG, INFO.

Kung itatakda mo ang antas ng pag-filter sa FATAL, kahit na ang mga mensahe ng ERROR ay itatapon.

"Mayroong dalawa pang antas ng kahalagahan na ginagamit kapag nagfi-filter: OFF, na nagtatapon ng lahat ng mensahe; at LAHAT, na nagpapakita ng lahat ng mensahe (walang itinatapon)."

"Paano at saan ako magse-set up ng pag-filter?"

"Sasabihin ko sa iyo nang walang karagdagang abala."

"Karaniwan, ang mga setting ng log4j logger ay tinukoy sa log4j.properties file."

Maaari mong tukuyin ang maramihang mga appender object sa file na ito. Ang data ay nakasulat sa mga bagay na ito. May mga data source, at may mga appenders — mga bagay na magkasalungat ang layunin. Mga bagay na dinadaluyan ng data tulad ng tubig.

"Narito ang ilang mga halimbawa:"

Pag-log sa console
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Linya 1 at 4 - Ito ay mga komento

Linya 2 – Ipinapahiwatig namin ang antas ng pag-log na gusto namin. Itatapon ang lahat ng hindi gaanong mahalagang antas (DEBUG, TRACE).

Sa parehong lugar, nagdadagdag kami ng kuwit at pagkatapos ay ipahiwatig ang pangalan ng bagay (na kung saan namin naisip ang aming sarili) kung saan isusulat ang log. Ang mga linya 5-9 ay naglalaman ng mga setting nito.

Linya 5 – Tinukoy namin ang uri ng appender ( ConsoleAppender ).

Linya 6 – Eksaktong ipinapahiwatig namin kung saan kami nagsusulat ( System.out. ).

Linya 7 – Itinakda namin ang klase na mamamahala ng mga pattern ng conversion (PatternLayout).

Linya 8 – Itinakda namin ang pattern ng conversion na gagamitin para sa pagsusulat. Sa halimbawa sa itaas, ito ang petsa at oras.

"At narito ang hitsura ng pagsusulat sa isang file:"

Pag-log sa isang file
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"Itinakda ng Linya 2 ang antas ng pag-filter ng mensahe at ang pangalan ng appender object (sink)."

"Line 5 – Tinukoy namin ang uri ng file appender ( RollingFileAppender )."

"Line 6 - Tinukoy namin ang pangalan ng file kung saan isusulat ang log."

"Line 7 – Tinukoy namin ang maximum na laki ng log. Kapag nalampasan ang limitasyon sa laki na ito, isang bagong file ang gagawin."

"Line 8 – Tinukoy namin ang bilang ng mga lumang log file na iimbak."

"Mga Linya 9-10 – Itakda ang pattern ng conversion."

"I don't know what's happening here, but I can guess. That's encouraging."

"Magaling iyan. Pagkatapos narito ang isang halimbawa kung paano magsulat ng log sa isang file at sa console:"

Pag-log sa console at isang file
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

"Ah, kaya mo yan? Ang galing!"

"Yep. Maaari kang magdeklara ng maraming appenders hangga't gusto mo at i-customize ang bawat isa."

Higit pa rito, ang bawat appender ay maaaring magkaroon ng napaka-flexible na mga setting para sa pag-filter ng mensahe. Hindi lamang kami makakapagtalaga ng indibidwal na antas ng pag-filter ng mensahe sa bawat appender, ngunit maaari rin naming i-filter ang mga mensahe ayon sa package! Iyon ang dahilan kung bakit kailangan mong tukuyin ang isang klase kapag lumilikha ng isang logger (pinag-uusapan ko ang tungkol sa LoggerFactory.getLogger ).

"Halimbawa:"

Pag-log sa console at isang file
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"Mga Linya 6 at 15 – Itinakda namin ang sarili naming antas ng pag-filter para sa bawat appender."

"Mga Linya 20-23 – Tinukoy namin ang pangalan ng package at ang antas ng pag-filter para sa mga mensahe nito. Ang Log4j.logger ay isang prefix: ang pangalan ng package ay naka-highlight sa orange."

"Talaga? Kaya mo pa yan. Well, cool!"

"Siya nga pala, hindi kasama ang log4j o slf4j sa JDK. Kakailanganin mong i-download ang mga ito nang hiwalay. Magagawa mo iyon dito . Ngunit may isa pang paraan:"

" Hakbang 1 . Magdagdag ng mga import sa klase:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" Hakbang 2 . Ilagay ang cursor sa mga linyang ito at pindutin ang Alt+Enter sa IntelliJ IDEA"

" Hakbang 3 . Piliin ang 'File jar sa web» menu item.'

" Hakbang 4 . Piliin ang 'slf4j-log4j13.jar'"

" Hakbang 5 . Tukuyin kung saan ida-download ang library (jar)"

" Hakbang 6 . Gamitin ang mga klase na kailangan mo."

"Whoa! Anong araw na ito. Napakaraming bago at napakahusay!"

"Narito ang isa pang magandang artikulo sa pag-log: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"Sige, tama na. Magpahinga ka na, programmer."