Näkyvyys Java-sovellukseesi on ratkaisevan tärkeää, jotta ymmärrät, miten se toimii juuri nyt, miten se on toiminut joskus menneisyydessä ja voit lisätä ymmärrystäsi siitä, miten se voi toimia tulevaisuudessa. Useimmiten lokien analysointi on nopein tapa havaita, mikä meni pieleen, joten lokien käyttö Javassa on ratkaisevan tärkeää sovelluksesi suorituskyvyn ja kunnon varmistamiseksi sekä mahdollisten käyttökatkosten minimoimiseksi ja vähentämiseksi. Keskitetty loki- ja valvontaratkaisu auttaa lyhentämään Mean Time To Repair -aikaa parantamalla Ops- tai DevOps-tiimisi tehokkuutta.
Hyviä käytäntöjä noudattamalla saat enemmän arvoa lokeistasi ja helpotat niiden käyttöä. Pystyt helpommin paikantamaan virheiden ja heikon suorituskyvyn perimmäisen syyn ja ratkaisemaan ongelmat ennen kuin ne vaikuttavat loppukäyttäjiin. Kerron siis tänään joitakin parhaita käytäntöjä, joiden nimeen kannattaa vannoa, kun työskentelet Java-sovellusten parissa. Pureudutaanpa asiaan.
- Käytä vakiomuotoista lokikirjastoa
- Valitse appendereidesi viisaasti
- Käytä mielekkäitä viestejä
- Javan pinojälkien kirjaaminen
- Javan poikkeusten kirjaaminen
- Käytä sopivaa lokitasoa
- Log in JSON
- Pitäkää lokin rakenne johdonmukaisena
- Lisää kontekstiä lokeihisi
- Java Logging in Containers
- Ei saa lokata liikaa tai liian vähän
- Keep the Audience in Mind
- Välttäkää arkaluontoisen tiedon kirjaamista lokiin
- Käytä lokienhallintaratkaisua keskittääksesi & Seuraa Java-lokeja
- Johtopäätös
Käytä vakiomuotoista lokikirjastoa
Loggaaminen Javassa voidaan tehdä muutamalla eri tavalla. Voit käyttää omaa lokikirjastoa, yleistä API:ta tai jopa vain kirjoittaa lokit tiedostoon tai suoraan omaan lokijärjestelmään. Kun valitset lokikirjastoa järjestelmääsi, mieti kuitenkin etukäteen. Huomioon otettavia ja arvioitavia asioita ovat suorituskyky, joustavuus, sovellukset uusia lokien keskittämisratkaisuja varten ja niin edelleen. Jos sidot itsesi suoraan yhteen kehykseen, siirtyminen uudempaan kirjastoon voi viedä huomattavan paljon työtä ja aikaa. Pidä tämä mielessä ja valitse API, joka antaa sinulle joustavuutta vaihtaa lokikirjastoja tulevaisuudessa. Aivan kuten vaihdettaessa Log4j:stä Logbackiin ja Log4j 2:een, SLF4J API:ta käytettäessä sinun tarvitsee vain vaihtaa riippuvuutta, ei koodia.
Jos Java-lokikirjastot ovat sinulle uusia, tutustu aloittelijan oppaisiin:
- Log4j-opas
- Logback-opas
- Log4j2-opas
- SLF4J-opas
Valitse appendereidesi viisaasti
Appendereiden avulla määritetään, minne lokitapahtumasi toimitetaan. Yleisimmät appenderit ovat Konsoli- ja Tiedosto-appenderit. Vaikka ne ovat hyödyllisiä ja laajalti tunnettuja, ne eivät välttämättä täytä tarpeitasi. Saatat esimerkiksi haluta kirjoittaa lokit asynkronisesti tai haluat toimittaa lokitiedot verkon kautta käyttämällä Syslogin kaltaisia appenderejä, esimerkiksi näin:
<Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %level %c - %m%n"/> </Console> <Syslog name="Syslog" host="logsene-syslog-receiver.sematext.com" port="514" protocol="TCP" format="RFC5424" appName="11111111-2222-3333-4444-555555555555" facility="LOCAL0" mdcId="mdc" newLine="true"/></Appenders>
Kannattaa kuitenkin muistaa, että edellä esitetyn kaltaisten appendereiden käyttäminen tekee lokiputkistasi alttiin verkkovirheille ja tiedonsiirtohäiriöille. Tämä voi johtaa siihen, että lokit eivät pääse perille, mikä ei välttämättä ole hyväksyttävää. Haluat myös välttää järjestelmään vaikuttavaa lokitusta, jos appenderi on suunniteltu estävällä tavalla. Saat lisätietoja tutustumalla lokikirjastot vs. lokin lähettäjät -blogikirjoitukseemme.
Käytä mielekkäitä viestejä
Yksi ratkaisevista asioista lokien luomisessa, mutta yksi ei niin helpoista, on mielekkäiden viestien käyttäminen. Lokitapahtumiesi tulisi sisältää viestejä, jotka ovat ainutlaatuisia kyseisessä tilanteessa, kuvaavat niitä selkeästi ja informoivat niitä lukevaa henkilöä. Kuvittele, että sovelluksessasi tapahtui tietoliikennevirhe. Voisit tehdä sen näin:
LOGGER.warn("Communication error");
Mutta voisit myös luoda viestin näin:
LOGGER.warn("Error while sending documents to events Elasticsearch server, response code %d, response message %s. The message sending will be retried.", responseCode, responseMessage);
Voit helposti nähdä, että ensimmäinen viesti informoi lokitietoja lukevaa henkilöä joistakin viestintäongelmista. Kyseinen henkilö saa luultavasti kontekstin, lokinpitäjän nimen ja rivinumeron, jossa varoitus tapahtui, mutta siinä kaikki. Saadakseen lisää kontekstiä hänen olisi katsottava koodia, tiedettävä, mihin koodin versioon virhe liittyy, ja niin edelleen. Tämä ei ole hauskaa eikä useinkaan helppoa, eikä ainakaan mitään sellaista, mitä haluaisi tehdä yrittäessään vianmääritystä tuotantoon liittyvässä ongelmassa mahdollisimman nopeasti.
Toinen viesti on parempi. Se antaa tarkat tiedot siitä, millainen viestintävirhe tapahtui, mitä sovellus teki sillä hetkellä, minkä virhekoodin se sai ja mikä oli etäpalvelimen vastaus. Lopuksi se myös ilmoittaa, että viestin lähettämistä yritetään uudelleen. Tällaisten viestien kanssa työskentely on ehdottomasti helpompaa ja miellyttävämpää.
Loppujen lopuksi mieti viestin kokoa ja sanamäärää. Älä kirjaa tietoja, jotka ovat liian laajasanaisia. Nämä tiedot on tallennettava jonnekin, jotta niistä olisi hyötyä. Yksi hyvin pitkä viesti ei ole ongelma, mutta jos tuo rivi toistuu satoja kertoja minuutissa ja sinulla on paljon sanavalmiita lokitietoja, tällaisten tietojen pidempi säilyttäminen voi olla ongelmallista, ja loppujen lopuksi se myös maksaa enemmän.
Javan pinojälkien kirjaaminen
Yksi erittäin tärkeistä Javan lokitietojen kirjaamisen osista ovat Javan pinojäljet. Tutustu seuraavaan koodiin:
package com.sematext.blog.logging;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import java.io.IOException;public class Log4JExceptionNoThrowable { private static final Logger LOGGER = LogManager.getLogger(Log4JExceptionNoThrowable.class); public static void main(String args) { try { throw new IOException("This is an I/O error"); } catch (IOException ioe) { LOGGER.error("Error while executing main thread"); } }}
Ylläoleva koodi johtaa poikkeuksen heittämiseen ja lokiviesti, joka tulostuu konsoliin oletuskokoonpanollamme näyttää seuraavalta:
11:42:18.952 ERROR - Error while executing main thread
Kuten huomaat, siinä ei ole paljon tietoa. Tiedämme vain, että ongelma tapahtui, mutta emme tiedä, missä se tapahtui tai mikä ongelma oli jne. Ei kovin informatiivista.
Katsotaan nyt samaa koodia hieman muutetulla lokilausekkeella:
package com.sematext.blog.logging;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import java.io.IOException;public class Log4JException { private static final Logger LOGGER = LogManager.getLogger(Log4JException.class); public static void main(String args) { try { throw new IOException("This is an I/O error"); } catch (IOException ioe) { LOGGER.error("Error while executing main thread", ioe); } }}
Kuten näet, tällä kertaa olemme sisällyttäneet itse poikkeusobjektin lokiviestiin:
LOGGER.error("Error while executing main thread", ioe);
Tällöin konsolissa olisi oletuskonfiguraatiollamme seuraavanlainen virheloki:
11:30:17.527 ERROR - Error while executing main threadjava.io.IOException: This is an I/O error at com.sematext.blog.logging.Log4JException.main(Log4JException.java:13)
Se sisältäisi relevanttia informaatiota – i.eli luokan nimen, metodin, jossa ongelma ilmeni, ja lopuksi rivinumeron, jossa ongelma ilmeni. Todellisissa tilanteissa pinojäljet ovat tietysti pidempiä, mutta ne kannattaa sisällyttää, jotta saat riittävästi tietoa kunnolliseen virheenkorjaukseen.
Kun haluat lisätietoja Java-pinojälkien käsittelystä Logstashilla, katso Monirivisten pinojälkien käsittely Logstashilla tai tutustu Logagentiin, joka voi tehdä sen puolestasi valmiiksi.
Javan poikkeusten kirjaaminen
Käsitellessäsi Javan poikkeuksia ja pinojälkiä sinun ei pitäisi ajatella vain koko pinojälkeä, rivejä, joilla ongelma ilmeni, ja niin edelleen. Kannattaa myös miettiä, miten poikkeuksia ei käsitellä.
Vältä poikkeusten hiljaista huomiotta jättämistä. Et halua jättää huomiotta jotain tärkeää. Älä tee esimerkiksi näin:
try { throw new IOException("This is an I/O error");} catch (IOException ioe) {}
Älä myöskään vain kirjaa poikkeusta ja heitä sitä eteenpäin. Se tarkoittaa, että olet juuri työntänyt ongelman ylöspäin suorituspinossa. Vältä myös tällaisia asioita:
try { throw new IOException("This is an I/O error");} catch (IOException ioe) { LOGGER.error("I/O error occurred during request processing", ioe); throw ioe;}
Jos olet kiinnostunut oppimaan lisää poikkeuksista, lue oppaamme Javan poikkeuskäsittelystä, jossa käsittelemme kaiken siitä, mitä ne ovat ja miten ne pyydystetään ja korjataan.
Käytä sopivaa lokitasoa
Kirjoittaessasi sovelluskoodia mieti kahdesti tiettyä lokiviestiä. Kaikki tiedot eivät ole yhtä tärkeitä, eikä jokainen odottamaton tilanne ole virhe tai kriittinen viesti. Käytä myös lokitasoja johdonmukaisesti – samantyyppisen tiedon tulisi olla samantyyppisellä vakavuustasolla.
Kumpikin SLF4J facade ja jokainen käyttämäsi Java-loggauskehys tarjoavat metodeja, joita voidaan käyttää oikean lokitason määrittämiseen. Esimerkiksi:
LOGGER.error("I/O error occurred during request processing", ioe);
Log in JSON
Jos aiomme lokata ja tarkastella tietoja manuaalisesti tiedostossa tai vakiotulosteessa, niin suunniteltu lokitus on enemmän kuin hyvä. Se on käyttäjäystävällisempi – olemme tottuneet siihen. Mutta se on toteuttamiskelpoinen vain hyvin pienille sovelluksille ja silloinkin on suositeltavaa käyttää jotain, joka mahdollistaa metriikkadatan korreloinnin lokien kanssa. Tällaisten toimintojen tekeminen terminaali-ikkunassa ei ole hauskaa, ja joskus se ei yksinkertaisesti ole mahdollista. Jos haluat tallentaa lokit lokien hallinta- ja keskittämisjärjestelmään, kannattaa lokit tallentaa JSON-muodossa. Tämä johtuu siitä, että jäsennys ei tule ilmaiseksi – se tarkoittaa yleensä säännöllisten lausekkeiden käyttöä. Voit tietysti maksaa tuon hinnan lokinsiirtimessä, mutta miksi tehdä niin, jos voit helposti logata JSONissa. JSONina kirjaaminen tarkoittaa myös helppoa stack tracesin käsittelyä, joten vielä yksi etu. No, voit myös vain lokata Syslog-yhteensopivaan kohteeseen, mutta se on eri juttu.
Useimmissa tapauksissa JSON-loggauksen ottamiseksi käyttöön Java-loggauskehyksessäsi riittää, että otat mukaan oikean konfiguraation. Oletetaan esimerkiksi, että koodimme sisältää seuraavan lokiviestin:
LOGGER.info("This is a log message that will be logged in JSON!");
Konfiguroidaksemme Log4J 2:n kirjoittamaan lokiviestejä JSON-muodossa sisällyttäisimme seuraavan konfiguraation:
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <JSONLayout compact="true" eventEol="true"> </JSONLayout> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers></Configuration>
Tulos näyttäisi seuraavalta:
{"instant":{"epochSecond":1596030628,"nanoOfSecond":695758000},"thread":"main","level":"INFO","loggerName":"com.sematext.blog.logging.Log4J2JSON","message":"This is a log message that will be logged in JSON!","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":1,"threadPriority":5}
Pitäkää lokin rakenne johdonmukaisena
Lokitapahtumiesi rakenteen tulisi olla johdonmukainen. Tämä ei päde vain yhden sovelluksen tai mikropalvelujoukon sisällä, vaan sitä tulisi soveltaa koko sovelluspinossa. Kun lokitapahtumat ovat rakenteeltaan samankaltaisia, niitä on helpompi tarkastella, verrata, korreloida tai yksinkertaisesti tallentaa ne omaan tietovarastoon. Järjestelmistäsi tulevia tietoja on helpompi tarkastella, kun tiedät, että niillä on yhteisiä kenttiä, kuten vakavuus ja isäntänimi, joten voit helposti pilkkoa ja paloitella tietoja näiden tietojen perusteella. Inspiraatiota saat katsomalla Sematext Common Schema, vaikka et olisikaan Sematext-käyttäjä.
Rakenteen säilyttäminen ei tietenkään ole aina mahdollista, koska koko pinosi koostuu ulkoisesti kehitetyistä palvelimista, tietokannoista, hakukoneista, jonoista jne. joista jokaisella on omat lokinsa ja lokimuotonsa. Sinun ja tiimisi mielenterveyden säilyttämiseksi minimoi kuitenkin hallitsemiesi erilaisten lokiviestirakenteiden määrä.
Yksi keino yhteisen rakenteen säilyttämiseen on käyttää samaa mallia lokeissa, ainakin niissä, jotka käyttävät samaa lokikehystä. Jos esimerkiksi sovelluksesi ja mikropalvelusi käyttävät Log4J 2:ta, voisit käyttää tällaista mallia:
<PatternLayout> <Pattern>%d %p %c{35}:%L - %m%n</Pattern></PatternLayout>
Käyttämällä yhtä tai hyvin rajattua joukkoa malleja voit olla varma siitä, että lokimuotojen määrä pysyy pienenä ja hallittavana.
Lisää kontekstiä lokeihisi
Tiedon konteksti on tärkeä, ja meille kehittäjille ja DevOps-tahojen edustajille lokiviesti on tietoa. Katso seuraavaa lokimerkintää:
An error occurred!
Tiedämme, että jossain sovelluksessa ilmeni virhe. Emme tiedä, missä se tapahtui, emme tiedä, millainen virhe se oli, tiedämme vain, milloin se tapahtui. Katso nyt viestiä, jossa on hieman enemmän asiayhteystietoa:
com.sematext.blog.logging.ParsingErrorExample - A parsing error occurred for user with id 1234!
Sama lokitietue, mutta paljon enemmän asiayhteystietoa. Tiedämme säikeen, jossa se tapahtui, tiedämme, missä luokassa virhe syntyi. Muokkasimme viestiä niin, että se sisältää myös käyttäjän, jolle virhe tapahtui, jotta voimme tarvittaessa ottaa yhteyttä käyttäjään. Voisimme myös sisällyttää lisätietoja, kuten diagnostisia konteksteja. Mieti mitä tarvitset ja sisällytä se.
Kontekstitietojen sisällyttämiseksi sinun ei tarvitse tehdä paljoakaan sen koodin suhteen, joka on vastuussa lokiviestin tuottamisesta. Esimerkiksi Log4J 2:n PatternLayout antaa sinulle kaiken, mitä tarvitset kontekstitietojen sisällyttämiseen. Voit käyttää hyvin yksinkertaista mallia, kuten tätä:
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n"/>
Tällöin saat seuraavan kaltaisen lokiviestin:
17:13:08.059 INFO - This is the first INFO level log message!
Mutta voit myös sisällyttää mallin, joka sisältää paljon enemmän tietoa:
<PatternLayout pattern="%d{HH:mm:ss.SSS} %c %l %-5level - %msg%n"/>
Tällöin tuloksena on seuraavan kaltainen lokiviesti:
17:24:01.710 com.sematext.blog.logging.Log4j2 com.sematext.blog.logging.Log4j2.main(Log4j2.java:12) INFO - This is the first INFO level log message!
Java Logging in Containers
Ajattele ympäristöä, jossa sovelluksesi tulee toimimaan. Lokien konfiguroinnissa on eroa, kun Java-koodia ajetaan VM:ssä tai bare-metal-koneessa, se on erilaista, kun sitä ajetaan konttiympäristössä, ja tietenkin se on erilaista, kun Java- tai Kotlin-koodia ajetaan Android-laitteessa.
Konttiympäristössä tapahtuvan lokien konfiguroinnin määrittämiseksi sinun on valittava lähestymistapa, jonka haluat käyttää. Voit käyttää jotakin annetuista lokiohjaimista – kuten journaldia, logagentia, Syslogia tai JSON-tiedostoa. Muista tätä varten, että sovelluksesi ei saa kirjoittaa lokitiedostoa kontin ephemeral-tallennustilaan, vaan vakiotulosteeseen. Se onnistuu helposti konfiguroimalla lokikehyksesi kirjoittamaan lokin konsoliin. Esimerkiksi Log4J 2:n kanssa voit käyttää vain seuraavaa sovelluskonfiguraatiota:
<Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} - %m %n"/> </Console></Appenders>
Voit myös jättää lokiohjaimet kokonaan pois ja lähettää lokit suoraan keskitettyyn lokiratkaisuusi, kuten Sematext Cloud -palveluumme:
<Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %level %c - %m%n"/> </Console> <Syslog name="Syslog" host="logsene-syslog-receiver.sematext.com" port="514" protocol="TCP" format="RFC5424" appName="11111111-2222-3333-4444-555555555555" facility="LOCAL0" mdcId="mdc" newLine="true"/></Appenders>
Ei saa lokata liikaa tai liian vähän
Kehittäjinä meillä on taipumus ajatella, että kaikki voi olla tärkeää – meillä on taipumus merkitä algoritmi- tai liiketoimintakoodimme jokainen vaihe tärkeäksi. Toisaalta teemme joskus päinvastoin – emme lisää lokitusta sinne, minne pitäisi, tai lokitamme vain FATAL- ja ERROR-logitasoja. Molemmat lähestymistavat eivät toimi kovin hyvin. Kun kirjoitat koodia ja lisäät lokitusta, mieti, mikä on tärkeää, jotta näet, toimiiko sovellus oikein, ja mikä on tärkeää, jotta voit diagnosoida sovelluksen virheellisen tilan ja korjata sen. Käytä tätä ohjenuorana päättäessäsi, mitä ja minne lokitetaan. Pidä mielessäsi, että liian monen lokin lisääminen johtaa tietoväsymykseen ja liian vähäinen tiedonsaanti johtaa kyvyttömyyteen vianmääritykseen.
Keep the Audience in Mind
Useimmissa tapauksissa et ole ainoa henkilö, joka tarkastelee lokeja. Muista aina, että. On useita toimijoita, jotka saattavat katsoa lokeja.
Kehittäjä saattaa katsoa lokeja vianmääritystä varten tai virheenkorjausistuntojen aikana. Tällaisille henkilöille lokit voivat olla yksityiskohtaisia, teknisiä ja sisältää hyvin syvällistä tietoa siitä, miten järjestelmä toimii. Tällaisella henkilöllä on myös pääsy koodiin tai hän jopa tuntee koodin ja sen voi olettaa.
Tällöin on olemassa DevOps. Heille lokitapahtumia tarvitaan vianmääritykseen ja niiden pitäisi sisältää diagnostiikassa hyödyllistä tietoa. Voit olettaa tietämystä järjestelmästä, sen arkkitehtuurista, komponenteista ja komponenttien konfiguraatiosta, mutta sinun ei pitäisi olettaa tietämystä alustan koodista.
Viimeiseksi, sovelluksen lokitietoja voivat lukea käyttäjät itse. Tällaisessa tapauksessa lokien tulisi olla riittävän kuvaavia, jotta ne auttavat korjaamaan ongelman, jos se on edes mahdollista, tai antavat riittävästi tietoa käyttäjää auttavalle tukitiimille. Esimerkiksi Sematextin käyttäminen valvontaan edellyttää valvonta-agentin asentamista ja käyttämistä. Jos olet hyvin rajoittavan palomuurin takana eikä agentti pysty lähettämään metriikoita Sematextille, se kirjaa virheet kohdennetusti, joita Sematextin käyttäjät voivat myös itse tarkastella.
Voisimme mennä pidemmälle ja yksilöidä vielä enemmän toimijoita, jotka saattavat tutkia lokitietoja, mutta tämän lyhyen luettelon pitäisi antaa sinulle välähdys siitä, mitä sinun pitäisi miettiä, kun kirjoitat lokiviestejäsi.
Välttäkää arkaluontoisen tiedon kirjaamista lokiin
Arkaluonteista tietoa ei pitäisi olla lokitiedoissa tai se pitäisi peittää. Salasanat, luottokorttinumerot, sosiaaliturvatunnukset, käyttöoikeuskoodit ja niin edelleen – kaikki tämä voi olla vaarallista, jos se vuotaa tai jos siihen pääsevät käsiksi ne, joiden ei pitäisi nähdä sitä. On kaksi asiaa, jotka sinun pitäisi ottaa huomioon:
Harkitse, ovatko arkaluonteiset tiedot todella välttämättömiä vianetsinnän kannalta. Ehkä luottokortin numeron sijasta riittää tieto tapahtuman tunnisteesta ja tapahtuman päivämäärästä? Ehkä sosiaaliturvatunnusta ei tarvitse säilyttää lokitiedoissa, kun käyttäjätunnuksen voi helposti tallentaa. Mieti tällaisia tilanteita, mieti, mitä tietoja tallennat, ja kirjoita arkaluonteisia tietoja vain silloin, kun se on todella tarpeen.
Toinen asia on arkaluonteisia tietoja sisältävien lokien lähettäminen isännöidylle lokipalvelulle. On hyvin harvoja poikkeuksia, joissa seuraavia neuvoja ei pitäisi noudattaa. Jos lokiisi on tallennettu ja täytyy tallentaa arkaluonteisia tietoja, peitä tai poista ne ennen niiden lähettämistä keskitettyyn lokisäilytykseen. Useimmissa suosituissa lokien lähettäjissä, kuten omassa Logagentissamme, on toiminto, joka mahdollistaa arkaluonteisten tietojen poistamisen tai peittämisen.
Loppujen lopuksi arkaluonteisten tietojen peittäminen voidaan tehdä itse lokikehyksessä. Katsotaanpa, miten se voidaan tehdä laajentamalla Log4j 2:ta. Koodimme, joka tuottaa lokitapahtumia, näyttää seuraavalta (koko esimerkki löytyy Sematextin Githubista):
public class Log4J2Masking { private static Logger LOGGER = LoggerFactory.getLogger(Log4J2Masking.class); private static final Marker SENSITIVE_DATA_MARKER = MarkerFactory.getMarker("SENSITIVE_DATA_MARKER"); public static void main(String args) { LOGGER.info("This is a log message without sensitive data"); LOGGER.info(SENSITIVE_DATA_MARKER, "This is a a log message with credit card number 1234-4444-3333-1111 in it"); }}
Jos suorittaisit koko esimerkin Githubista, tuloste olisi seuraava:
21:20:42.099 - This is a log message without sensitive data21:20:42.101 - This is a a log message with credit card number ****-****-****-**** in it
Voit nähdä, että luottokortin numero on peitetty. Tämä tehtiin, koska lisäsimme mukautetun muuntimen, joka tarkistaa, kulkeutuuko annettu Marker pitkin lokitapahtumaa ja yrittää korvata määritellyn mallin. Tällaisen muuntimen toteutus näyttää seuraavalta:
@Plugin(name = "sample_logging_mask", category = "Converter")@ConverterKeys("sc")public class LoggingConverter extends LogEventPatternConverter { private static Pattern PATTERN = Pattern.compile("\b({4})-({4})-({4})-({4})\b"); public LoggingConverter(String options) { super("sc", "sc"); } public static LoggingConverter newInstance(final String options) { return new LoggingConverter(options); } @Override public void format(LogEvent event, StringBuilder toAppendTo) { String message = event.getMessage().getFormattedMessage(); String maskedMessage = message; if (event.getMarker() != null && "SENSITIVE_DATA_MARKER".compareToIgnoreCase(event.getMarker().getName()) == 0) { Matcher matcher = PATTERN.matcher(message); if (matcher.find()) { maskedMessage = matcher.replaceAll("****-****-****-****"); } } toAppendTo.append(maskedMessage); }}
Se on hyvin yksinkertainen, ja se voitaisiin kirjoittaa optimoidummin, ja sen pitäisi myös käsitellä kaikkia mahdollisia luottokorttien numeromuotoja, mutta se riittää tähän tarkoitukseen.
Ennen kuin hyppäämme koodin selitykseen, haluan myös näyttää tämän esimerkin log4j2.xml-konfiguraatiotiedoston:
<?xml version="1.0" encoding="UTF-8"?><Configuration status="WARN" packages="com.sematext.blog.logging"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} - %sc %n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers></Configuration>
Kuten näet, olemme lisänneet konfiguraatiossamme package-attribuutin kertoaksemme kehykselle, mistä konvertterimme pitää etsiä. Sitten olemme käyttäneet %sc-mallia antaaksemme lokiviestin. Teemme näin, koska emme voi korvata oletusarvoista %m-kuviota. Kun Log4j2 löytää %sc-kuvion, se käyttää muunninta, joka ottaa lokitapahtuman muotoillun viestin, käyttää yksinkertaista regexiä ja korvaa tiedon, jos se löytyy. Näin yksinkertaista se on.
Yksi huomioitava asia tässä on se, että käytämme Marker-toimintoa. Regex-sovitus on kallista, emmekä halua tehdä sitä jokaiselle lokiviestille. Siksi merkitsemme luodulla Markerilla ne lokitapahtumat, jotka pitäisi käsitellä, jolloin vain merkityt tarkistetaan.
Käytä lokienhallintaratkaisua keskittääksesi & Seuraa Java-lokeja
Sovellusten monimutkaisuuden myötä myös lokien määrä kasvaa. Saatat selvitä siitä, että kirjaat lokit tiedostoon ja käytät lokeja vain silloin, kun vianmääritystä tarvitaan, mutta kun tietomäärä kasvaa, vianmäärityksestä tulee nopeasti vaikeaa ja hidasta tällä tavoin Kun näin käy, harkitse lokienhallintaratkaisun käyttämistä lokien keskittämiseen ja seurantaan. Voit valita joko avoimen lähdekoodin ohjelmistoon perustuvan sisäisen ratkaisun, kuten Elastic Stackin, tai käyttää jotakin markkinoilla saatavilla olevaa lokienhallintatyökalua, kuten Sematext Logsia.
Täysin hallinnoitu lokien keskittämisratkaisu antaa sinulle vapauden siitä, että sinun ei tarvitse hallinnoida enää toista, tavallisesti melko monimutkaista infrastruktuurin osaa. Sen sijaan voit keskittyä sovellukseesi ja sinun tarvitsee määrittää vain lokien lähetys. Saatat haluta sisällyttää lokit, kuten JVM:n roskienkeruulokit, hallittuun lokiratkaisuun. Kun olet ottanut ne käyttöön JVM:llä toimivia sovelluksiasi ja järjestelmiäsi varten, haluat koota lokit yhteen paikkaan lokien korrelointia, lokianalyysiä ja JVM-instanssien roskienkeräyksen virittämistä varten. Tällaiset metriikoiden kanssa korreloidut lokit ovat korvaamaton tietolähde roskienkeruuseen liittyvien ongelmien vianmäärityksessä.
Jos olet kiinnostunut näkemään, miten Sematext Logs pärjää samankaltaisille ratkaisuille, voit tutustua artikkeliin parhaista lokienhallintaohjelmistoista tai blogikirjoitukseen, jossa tarkastelemme joitain parhaita lokianalyysityökaluja, mutta suosittelemme käyttämään 14 päivän ilmaista kokeilujaksoa, jotta voit tutustua sen ominaisuuksiin täysin. Kokeile sitä ja katso itse!
Johtopäätös
Kaikkien hyvien käytäntöjen sisällyttäminen ei välttämättä ole helppoa toteuttaa heti, varsinkaan sovelluksissa, jotka ovat jo käytössä ja toimivat tuotannossa. Mutta jos käytät aikaa ja otat ehdotukset käyttöön yksi kerrallaan, alat nähdä lokien hyödyllisyyden lisääntyvän. Jos haluat lisää vinkkejä siitä, miten saat kaiken mahdollisen irti lokeistasi, suosittelemme, että luet myös toisen artikkelimme lokien parhaista käytännöistä, jossa kerromme, mitä sisäisiä ja ulkoisia sääntöjä sinun tulisi noudattaa riippumatta siitä, minkä tyyppisen sovelluksen kanssa työskentelet. Ja muista, että me Sematextillä autamme organisaatioita niiden lokiasetusten kanssa tarjoamalla lokikonsultointia, joten ota yhteyttä, jos sinulla on ongelmia, niin autamme mielellämme.
Vastaa