CodeGym /Blog Jawa /Acak /Logging: apa, carane, ngendi, lan karo apa?
John Squirrels
tingkat
San Francisco

Logging: apa, carane, ngendi, lan karo apa?

Diterbitake ing grup
Halo kabeh wong ing komunitas CodeGym! Logging: apa, carane, ngendi, lan karo apa?  - 1 Dina iki ayo ngomong babagan logging:
  1. Apa iku, kok ana, nalika sampeyan kudu nggunakake, nalika sampeyan kudu nyingkiri.
  2. Implementasi logging apa sing kasedhiya ing Jawa, lan apa sing kudu sampeyan lakoni karo kabeh opsi logging iki.
  3. Lan tingkat log. Kita bakal ngrembug apa appender lan carane ngatur kanthi bener.
  4. Node logging lan carane ngatur kanthi bener supaya kabeh bisa mlaku kaya sing dikarepake.
Materi iki ditrapake kanggo pamirsa sing akeh. Bakal cetha kanggo sapa wae sing lagi ngerti basa Jawa, uga wong sing wis kerja nanging mung njelajah logger.info("log something"); Ayo!

Napa sampeyan kudu logging?

Ayo goleki sawetara kasus nyata nalika logging bisa ngatasi masalah. Iki minangka conto saka karyaku. Ana titik ing ngendi aplikasi digabungake karo layanan liyane. Aku nggunakake logging ing titik kasebut kanggo nggawe "alibi" : yen integrasi ora bisa digunakake, mula dadi gampang kanggo nemtokake sisih endi sing duwe masalah. Iku uga seng di pengeni kanggo log informasi penting sing disimpen ing database. Contone, nggawe pangguna admin. Iki minangka jinis sing paling apik kanggo log.

Piranti kanggo mlebu ing Jawa

Ing antarane solusi logging sing kondhang ing Jawa, kita bisa nyorot ing ngisor iki:
  • Log4j
  • JUL — java.util.logging
  • JCL — Jakarta Commons Logging
  • Logback
  • SLF4J - Prasaja Logging Facade kanggo Jawa
Kita bakal menehi ringkesan saben wong. Banjur kita bakal njupuk slf4j - log4j naleni minangka basis saka diskusi praktis. Iki bisa uga katon aneh saiki, nanging aja kuwatir: ing pungkasan artikel, kabeh bakal jelas.

System.err.println

Ing wiwitan, ana System.err.println (nampilake entri log ing console). Malah dina iki, technique iki digunakake kanggo cepet log nalika debugging. Mesthi wae, ora ana setelan sing bakal dibahas ing kene, mula mung elinga metode iki lan kita bakal nerusake.

Log4j

Iki minangka solusi lengkap sing digawe para pangembang amarga kabutuhan. Asil minangka alat sing menarik banget sing bisa digunakake. Amarga macem-macem kahanan, solusi iki ora ana ing JDK, kasunyatan sing ngganggu kabeh komunitas. Log4j duwe opsi konfigurasi sing ngidini sampeyan ngaktifake mlebu paket com.example.typelan mateni ing com.example.type.genericsubpaket. Iki ndadekake iku bisa kanggo cepet ngilangi kode sing ora perlu kanggo mlebu. Iku penting kanggo Wigati kene sing ana rong versi Log4j: 1.2.x lan 2.xx, lan padha ora kompatibel karo saben liyane . Log4j nambahake konsep appender(alat sing digunakake kanggo nulis log) lan tata letak (format log). Iki ngidini sampeyan log mung apa sing perlu lan log iku mung carane sampeyan perlu iku. Kita bakal ngomong luwih lengkap babagan appender mengko.

JUL — java.util.logging

Salah sawijining keuntungan utama saka solusi iki yaiku JUL kalebu ing JDK (Java Development Kit). Sayange, nalika dikembangake, pangripta ora adhedhasar utilitas Log4j sing populer, nanging solusi saka IBM. Kaputusan kasebut duwe akibat. Kasunyatane ora ana sing nggunakake JUL saiki. Tingkat log ing JUL beda karo Logback, Log4j, lan Slf4j. Iki nggawe luwih angel kanggo ngerti siji liyane. Nggawe logger kurang luwih padha. Kanggo nindakake iki, sampeyan kudu ngimpor:

java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Jeneng kelas wis liwati, supaya kita ngerti saka ngendi logging kita bakal teka. Diwiwiti karo Jawa 8, sampeyan bisa lulus Supplier<String>. Iki mbantu kita maca lan nggawe baris mung nalika kita pancene mbutuhake, tinimbang saben wektu, kaya sadurunge. Mung kanthi rilis Java 8, pangembang pungkasane ngrampungake masalah penting lan nggawe JUL bisa digunakake. Yaiku, metode kanthi Supplier<String> msgSupplierparameter, kaya ing ngisor iki:

public void info(Supplier<String> msgSupplier) {
   log(Level.INFO, msgSupplier);
}

JCL — Jakarta Commons Logging

Amarga ora ana standar industri babagan logging kanggo wektu sing suwe lan akeh wong sing nggawe logger khusus dhewe, keputusan kasebut digawe kanggo ngeculake JCL, bungkus umum sing bisa digunakake ing ndhuwur liyane. Kenging punapa? Kadhangkala dependensi sing ditambahake ing proyek kasebut nggunakake logger sing beda tinimbang sing ana ing proyek kasebut. Amarga iki, dheweke ditambahake ing proyek kasebut minangka dependensi transitif, lan iki nggawe masalah nyata nalika nyoba nggabungake kabeh. Sayange, bungkus kasebut ora bisa digunakake lan ora nambah apa-apa. Mesthi bakal trep yen kabeh wong nggunakake JCL. Nanging dudu sing kedadeyan, mula nggunakake JCL dudu ide sing paling apik saiki.

Logback

Path open-source eri ... Pengembang sing padha sing nulis Log4j uga nulis Logback minangka kerangka logging penerus. Iki adhedhasar gagasan sing padha karo Log4j. Bedane ing Logback yaiku:
  • kinerja apik
  • ditambahaké support native kanggo Slf4j
  • opsi nyaring ditambahi
Kanthi gawan, Logback ora mbutuhake konfigurasi, lan ngrekam kabeh acara ing tingkat DEBUG lan luwih dhuwur. Yen sampeyan mbutuhake sawetara pangaturan dhewe, sampeyan bisa entuk liwat konfigurasi XML:

<configuration> 
    <appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
        <file>app.log</file> 
        <encoder> 
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern> 
        </encoder> 
    </appender> 
    <logger name="org.hibernate.SQL" level="DEBUG" /> 
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" /> 
    <root level="info"> 
        <appender-ref ref="FILE" /> 
    </root> 
</configuration>

SLF4J - Prasaja Logging Facade kanggo Jawa

Ing taun 2006, salah sawijining pendiri Log4j ninggalake proyek kasebut lan nggawe Slf4j (Simple Logging Facade for Java), bungkus kanggo Log4j, JUL, common-logging, lan Logback. Nalika sampeyan bisa ndeleng, kita wis maju menyang titik nggawe pambungkus liwat pambungkus ... Ing kasus iki, iku dipérang dadi rong bagéan: API sing digunakake ing aplikasi, lan implementasine sing ditambahake karo kapisah. dependensi kanggo saben jinis logging. Contone, slf4j-log4j12.jarlan slf4j-jdk14.jar. Sampeyan kudu nyambungake implementasine sing bener lan mung: kabeh proyek sampeyan bakal nggunakake. Slf4j ndhukung kabeh fitur paling anyar, kayata format strings kanggo logging. Sadurunge, ana masalah kaya ngono. Ayo kita nggawe entri log kaya iki:

log.debug("User " + user + " connected from " + request.getRemoteAddr());
Amarga operator concatenation, userobyek meneng dadi string thanks kanggo user.toString(). Iki mbutuhake wektu lan slows mudhun sistem. Lan sing bisa uga OK yen kita lagi debugging aplikasi. Kita miwiti nemokke masalah yen tingkat log kanggo kelas iki INFO utawa luwih. Ing tembung liyane, kita ngirim ora nulis entri log iki (kanggo INFO utawa luwih), lan kita ngirim ora nggunakake concatenation senar. Ing teori, perpustakaan logging dhewe kudu ngatasi iki. Kaya sing kedadeyan, iki dadi masalah paling gedhe ing versi pisanan Log4j. Ora menehi solusi sing apik, nanging disaranake nindakake kaya iki:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
Sing, tinimbang siji baris kode kanggo logging, padha disaranake nulis 3! Logging kudu nyilikake owah-owahan kode, lan telung baris cetha nerak sing pendekatan umum. Slf4j ora duwe masalah kompatibilitas karo JDK lan API, mula solusi sing apik langsung muncul:

log.debug("User {} connected from {}", user, request.getRemoteAddr());
ngendi {}nuduhake placeholders kanggo bantahan liwati kanggo cara. Yaiku, sing pisanan {}cocog karo user, lan sing nomer loro {}cocog karo request.getRemoteAddr(). Kanthi cara iki, kita bakal nindakake concatenation string mung yen tingkat log mbutuhake kita nulis entri log. Sawisé iku, Sjf4j wiwit cepet tuwuh ing popularitas. Saiki, iku solusi sing paling apik. Dadi, ayo goleki logging nggunakake slf4j-log4j12binding.

Apa sing kudu dicathet

Mesthi, sampeyan ora kudu nyathet kabeh. Iki asring ora perlu lan kadhangkala uga mbebayani. Contone, yen sampeyan nyathet data pribadhi wong liya lan bisa bocor, bakal ana masalah nyata, utamane ing proyek sing fokus ing pasar Barat. Nanging ana uga sing kudu sampeyan log :
  1. Wiwiti / pungkasan aplikasi. Kita kudu ngerti apa aplikasi kasebut pancen diwiwiti lan rampung kaya sing dikarepake.
  2. Masalah keamanan. Ing kene bakal luwih apik kanggo log nyoba ngira sandhi wong, kedadeyan nalika admin mlebu, lsp.
  3. Negara aplikasi tartamtu . Contone, transisi saka siji negara menyang liyane ing proses bisnis.
  4. Informasi debug tartamtu bebarengan karo tingkat log sing cocog.
  5. Skrip SQL tartamtu. Ana kasus ing donya nyata yen iki perlu. Nanging maneh, kanthi trampil nyetel level log, sampeyan bisa entuk asil sing apik banget.
  6. Utas sing mlaku bisa dicathet nalika verifikasi manawa samubarang bisa digunakake kanthi bener.

Kesalahan populer ing logging

Ana akeh nuansa ing kene, nanging kita bakal nyebutake sawetara kesalahan umum:
  1. logging kakehan. Sampeyan ora kudu nyathet saben langkah sing bisa sacara teoritis penting. Kene aturan apik: Log ngirim ora ngluwihi 10% saka mbukak. Yen ora, bakal ana masalah kinerja.
  2. Log kabeh data menyang siji file. Ing sawetara titik, iki bakal nggawe angel banget kanggo maca / nulis log, ora kanggo sebutno kasunyatan sing sistem tartamtu duwe watesan ing ukuran file.
  3. Nggunakake level log sing salah. Saben level log nduweni wates sing jelas, lan kudu diajeni. Yen wates ora cetha, sampeyan bisa teka menyang persetujuan bab kang tingkat nggunakake.

Tingkat log

x: katon
FATAL ERROR WARNING INFO DEBUG TRACE KABEH
OFF
FATAL x
ERROR x x
WARNING x x x
INFO x x x x
DEBUG x x x x x
TRACE x x x x x x
KABEH x x x x x x x
Apa level log? Supaya bisa nggawe hirarki entri log, konvensi lan watesan tartamtu dibutuhake. Mulane tingkat log dienalake. Tingkat disetel ing aplikasi. Yen entri ana ing sangisore level sing ditemtokake, mula ora dicathet. Contone, kita duwe log sing digunakake nalika debugging aplikasi. Sajrone operasi normal (nalika aplikasi digunakake kanggo tujuan sing dituju), log kasebut ora dibutuhake. Mulane, tingkat log luwih dhuwur tinimbang kanggo debugging. Ayo katon ing tingkat log nggunakake Log4j. Saliyane JUL, solusi liyane nggunakake level log sing padha. Ing ngisor iki ana ing urutan sing mudhun:
  • OFF: Ora ana entri log sing direkam; kabeh ora digatekake.
  • FATAL: Kesalahan sing ngalangi aplikasi supaya ora bisa digunakake. Contone, "JVM metu saka kesalahan memori".
  • ERROR: Kasalahan ing tingkat iki nuduhake masalah sing kudu dirampungake. Kesalahan ora mungkasi aplikasi kanthi sakabehe. Panjaluk liyane bisa uga bener.
  • WARN: Entri log sing makili bebaya. Ana kedadeyan sing ora dikarepke, nanging sistem kasebut bisa ngatasi lan ngrampungake panjaluk kasebut
  • INFO: Entri log sing nuduhake tumindak penting ing aplikasi kasebut. Iki dudu kesalahan utawa bebaya. Padha samesthine acara sistem.
  • DEBUG: Entri log kudu debug aplikasi. Kanggo mesthekake yen aplikasi nindakake apa sing dikarepake, utawa kanggo njlentrehake tumindak sing ditindakake dening aplikasi kasebut, yaiku "Metode 1".
  • TRACE: Entri log prioritas sing luwih murah kanggo debugging. Tingkat log paling murah.
  • ALL: Tingkat log kanggo nulis kabeh entri log aplikasi.
Ing tingkat log INFO diaktifake nang endi wae ing aplikasi, banjur entri kanggo saben tingkat bakal mlebu, saka INFO kanggo FATAL. Yen level log FATAL disetel, mung entri log karo level kasebut sing bakal ditulis.

Log lan ngirim log: Appender

Ayo dipikirake carane kabeh iki bisa digunakake nalika nggunakake Log4j, sing menehi akeh kesempatan kanggo nulis / ngirim log:
  • kanggo nulis menyang file -DailyRollingFileAppender
  • kanggo nulis informasi menyang konsol -ConsoleAppender
  • kanggo nulis log menyang database -JDBCAppender
  • kanggo ngatur ngirim log liwat TCP/IP -TelnetAppender
  • kanggo mesthekake yen logging ora mengaruhi kinerja -AsyncAppender
Ana sawetara implementasine liyane: dhaftar lengkap kasedhiya kene . Miturut cara, yen appender sing sampeyan butuhake ora ana, ora masalah. Sampeyan bisa nulis appender dhewe kanthi ngleksanakake antarmuka Appender , sing Log4j ndhukung.

Node logging

Kanggo tujuan demonstrasi, kita bakal nggunakake antarmuka Slf4j, kanthi implementasine saka Log4j. Nggawe logger gampang banget: ing kelas sing jenenge MainDemo, sing bakal nindakake sawetara logging, kita kudu nambah ing ngisor iki:

org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MainDemo.class);
Iki bakal nggawe logger kanggo kita. Kanggo nggawe entri log, ana sawetara cara sing kasedhiya sing jenenge nggambarake level log sing bakal digunakake. Tuladhane:

logger.trace("Method 1 started with argument={}", argument);
logger.debug("Database updated with script = {}", script);
logger.info("Application has started on port = {}", port);
logger.warn("Log4j didn't find the log4j.properties file. Please fix this.");
logger.error("Connection refused to host = {}", host);
Senajan kita ngliwati kelas, jeneng pungkasan iku jeneng lengkap kelas, kalebu paket. Iki rampung supaya mengko sampeyan bisa dibagi log menyang simpul lan ngatur tingkat logging lan appender kanggo saben simpul. Contone, logger digawe ing com.github.romankh3.logginglecture.MainDemokelas. Jeneng kasebut menehi dhasar kanggo nggawe hirarki node logging. Simpul utama yaiku RootLogger tingkat ndhuwur . Iki minangka simpul sing nampa kabeh entri log kanggo kabeh aplikasi. Node sing isih ana bisa digambarake kaya ing ngisor iki: Logging: apa, carane, ngendi, lan karo apa?  - 3Appenders dikonfigurasi kanggo node logging tartamtu. Saiki kita bakal katon ing file log4j.properties kanggo ndeleng conto carane ngatur.

Pandhuan langkah-langkah dening-file log4j.properties

Kita bakal nyetel kabeh siji-sijine lan ndeleng apa sing bisa ditindakake:

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
Baris iki nyatakake yen kita ndhaptar appender CONSOLE, sing nggunakake implementasine org.apache.log4j.ConsoleAppender. Appender iki nulis informasi menyang console. Sabanjure, kita ndhaftar appender liyane. Iki bakal nulis menyang file:

log4j.appender.FILE=org.apache.log4j.RollingFileAppender
Wigati dimangerteni manawa appenders dhewe isih kudu dikonfigurasi. Sawise ndhaptar appenders, kita bisa nemtokake level log lan appenders sing bakal digunakake ing node.

log4j.rootLogger=DEBUG, CONSOLE, FILE

  • log4j.rootLogger tegese kita configuring simpul ROOT, kang ngemot kabeh entri log
  • Tembung pisanan sawise tandha padha nuduhake tingkat log minimal kanggo nulis (ing kasus kita, DEBUG)
  • Sawise koma, kita nuduhake kabeh appenders sing bakal digunakake.
Kanggo ngatur simpul log sing luwih spesifik, sampeyan bakal nggunakake entri kaya iki:

log4j.logger.com.github.romankh3.logginglecture=TRACE, OWN, CONSOLE
ngendi log4j.logger.digunakake kanggo referensi simpul tartamtu. Ing kasus kita, com.github.romankh3.logginglecture. Saiki ayo ngomong babagan konfigurasi appender CONSOLE:

# CONSOLE appender customization
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] : %c:%L : %m%n
Ing kene kita bisa ndeleng manawa bisa nyetel level tartamtu ing endi appender bakal digunakake. Iki minangka conto apa sing kedadeyan: umpamane pesen kanthi level INFO ditampa dening simpul log lan dikirim menyang appender sing ditugasake. Yen batesan appender disetel kanggo WARN, banjur nampa entri log nanging ora nindakake apa-apa. Sabanjure, kita kudu mutusake tata letak pesen sing bakal digunakake. Aku nggunakake PatternLayout ing conto, nanging ana akeh opsi liyane. Kita ora bakal nutupi ing artikel iki. Conto konfigurasi appender FILE:

# File appender customization
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./target/logging/logging.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.MaxBackupIndex=2
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[ %-5p] - %c:%L - %m%n
Sampeyan bisa ngatur file tartamtu sing bakal ditulis entri log, kaya sing bisa dideleng saka baris iki:

log4j.appender.FILE.File=./target/logging/logging.log
Entri ditulis menyang logging.logfile. Kanggo nyegah masalah karo ukuran file, sampeyan bisa ngatur maksimum, kang ing kasus iki 1MB. MaxBackupIndexnuduhake carane akeh file log kuwi bakal ana. Yen kita kudu nggawe file luwih saka iki, banjur file pisanan bakal dibusak. Kanggo ndeleng conto nyata ing ngendi logging dikonfigurasi, sampeyan bisa pindhah menyang repositori umum ing GitHub.

Nguatake apa sing wis kita rembugan

Coba dhewe kanggo nindakake kabeh sing wis diterangake:
  • Gawe proyek sampeyan dhewe sing padha karo conto ing ndhuwur.
  • Yen sampeyan ngerti carane nggunakake Maven, gunakake. Yen ora, waca tutorial iki , sing nerangake carane nyambungake perpustakaan.

Ing ringkesan

  1. Kita ngomong babagan solusi logging sing ana ing Jawa.
  2. Meh kabeh perpustakaan logging sing kondhang ditulis dening wong siji :D
  3. Kita sinau apa sing kudu lan ora kudu dicathet.
  4. Kita nemtokake tingkat log.
  5. Kita dikenalake menyang simpul log.
  6. We katon ing apa appender lan apa iku.
  7. Kita nggawe file log4j.proteties langkah demi langkah.

Bahan tambahan

  1. CodeGym: pelajaran Logger
  2. Mingguan Geekly: Java logging. Hello donya
  3. Coding Horror: Masalah Kanthi Logging
  4. YouTube: Pangerten Jawa Logging Neraka - Dasar. Jawa Logging Neraka & Carane tetep metu saka iku
  5. Log4j: Lampiran
  6. Log4j: Tata letak
Deleng uga artikelku liyane:
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION