Kirjoittaja Aihe: Bash-tulkkia paikalla  (Luettu 5896 kertaa)

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Bash-tulkkia paikalla
« : 31.01.18 - klo:10.24 »
Moi

Funktioiden nimet kertovat varmaan enemmän kuin itse osaan kuvailla väärin.
Lokitiedostoja näillä jotenkin parsitaan tai muokataan.

Koodia: [Valitse]
sort_common_log () {
    local S_VVVV="\([0-9]\{4\}\)"
    local S_PP="\([0-9]\{2\}\)"
    local S_KKK="\(Jan\|Feb\|Mar\|Apr\|May\|Jun\|Jul\|Aug\|Sep\|Oct\|Nov\|Dec\)"
    local S_HH="\([0-2][0-9]\)"
    local S_MM="\([0-5][0-9]\)"
    local S_SS="\([0-5][0-9]\)"

    sed -n -e "s/\(.*\[${S_PP}\/${S_KKK}\/${S_VVVV}:${S_HH}:${S_MM}:${S_SS} +[0-9]\{4\}\].*\)/\4 \3 \2 \5 \6 \7 \1/p" | sort -k 1,1n -k 2,2M -k 3,3n -k 4,4n -k 5,5n -k 6,6n | cut -d" " -f7-

    }

Koodia: [Valitse]
sort_apache_log () {
    local S_VVVV="\([0-9]\{4\}\)"
    local S_PP="\([0-9]\{2\}\)"
    local S_KKK="\(Jan\|Feb\|Mar\|Apr\|May\|Jun\|Jul\|Aug\|Sep\|Oct\|Nov\|Dec\)"
    local S_HH="\([0-2][0-9]\)"
    local S_MM="\([0-5][0-9]\)"
    local S_SS="\([0-5][0-9]\)"

    sed -n -e "s/\(.*\[${S_PP}\/${S_KKK}\/${S_VVVV}:${S_HH}:${S_MM}:${S_SS} +0[2-3]00\].*\)/\4 \3 \2 \5 \6 \7 \1/p" | sort -k 1,1n -k 2,2M -k 3,3n -k 4,4n -k 5,5n -k 6,6n | cut -d' ' -f7-

}

Itselleni sen verran kuitenkin tuntematon osa-alue, etten alkanut edes tulkkaamaan noita vaan suosiolla kysyn.

Käsittääkseni lokitiedostojen parsimiseen on ihan valmiita ilmaisia skriptejä tai softia, joissa olisi jotain vastaavia "perusongelmia" ratkottu lokiformaattien välillä.

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #1 : 31.01.18 - klo:12.26 »
Minusta bash-koodi on tuossa ihan luettavaa. Selittelyä vaatii sed-koodi ja sed-koodiin upotettavat arvot, sekä sort ja cut-komennot jotka ovat Unix-peruskauraa, vaikkakin kryptisiä. Aoitetaan siis siitä pystytkö erottamaan mikä on bash:n osuus? Pystytkö erottamaan mikä on sed-komennon osuus? sort-komennon osuus? cut-komennon osuus? Koeta tutkia niitä ihan erikseen kutakin, ja kysy sitten lisää.

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #2 : 31.01.18 - klo:13.52 »
Kyllä tuosta nuo SL:t erottaa, mutta mitä ja miten tuossa putkituksessa tapahtuu, niin se on arvoitus.

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #3 : 31.01.18 - klo:15.07 »
Siinä muunnetaan ensin sed-komennolla lokirivien aikaleimat sellaiseen muotoon että sorttaus voidaan tehdä niiden avulla (eli vaihdetaan kenttien keskinäistä järjestystä ja muunnetaan kuukausien nimilyhenteet numeroiksi). Sitten sort-komennolla lajitellaan rivit mieleiseen järjestykseen, ja lopuksi cut-komennolla poimitaan sortatuilta riveiltä ne tiedot joka halutaan tulostaa.

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #4 : 31.01.18 - klo:15.39 »
Siinä muunnetaan ensin sed-komennolla lokirivien aikaleimat sellaiseen muotoon että sorttaus voidaan tehdä niiden avulla (eli vaihdetaan kenttien keskinäistä järjestystä ja muunnetaan kuukausien nimilyhenteet numeroiksi). Sitten sort-komennolla lajitellaan rivit mieleiseen järjestykseen, ja lopuksi cut-komennolla poimitaan sortatuilta riveiltä ne tiedot joka halutaan tulostaa.
Ootko tehny nämä skriptit? :)

Mitä nuo sortin kahvat ja parametrit on? Selvästi noissa on joku logiikka.

nm

  • Käyttäjä
  • Viestejä: 16246
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #5 : 31.01.18 - klo:16.16 »
Mitä nuo sortin kahvat ja parametrit on? Selvästi noissa on joku logiikka.

Koodia: [Valitse]
man sort
http://man7.org/linux/man-pages/man1/sort.1.html

Siinä määritellään sorttaus välilyönnillä erotetuille aikaleimakentille 1 (VVVV), 2 (KKK), 3 (PP), 4 (HH), 5 (MM) ja 6 (SS) eniten merkitsevästä vähiten merkitsevään. (Nuo kentät siis erotetaan ensin sedillä hakasulkujen sisältä eri kohdasta riviä ja kopioidaan rivin eteen eri järjestykseen.) Englanninkieliset kuukausilyhenteet sortataan valitsimella -M, eli niitä ei muunneta numeerisiksi missään vaiheessa. Muut kentät sortataan numeerisesti.

Sorttauksen jälkeen cut-komennolla leikataan lopusta alkuperäinen lokirivi sellaisenaan, eli tuloksena on alkuperäinen loki sortattuna aikajärjestykseen. Yleensähän lokitiedostot ovat jo aikajärjestyksessä, mutta tässä pyritään ilmeisesti ratkaisemaan tilanne, jossa useita lokitiedostoja on yhdistetty eri paikoista tai väärään aikajärjestykseen.


Itse käyttäisin tällaisiin hommiin Pythonia ja dateutil.parser -moduulia, joka lukee eri formaateissa olevia aikaleimoja ilman manuaalisia säätöjä. Apache-lokiparsereita ja vastaavia kyhäelmiä on toki Githubissa kymmenittäin tai sadoittain eri kielillä toteutettuna, jos tykkää käyttää valmista koodia.
« Viimeksi muokattu: 31.01.18 - klo:16.18 kirjoittanut nm »

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #6 : 31.01.18 - klo:16.23 »
Ootko tehny nämä skriptit? :)
En tekisi sitä noin, vaikka tiedän että se saattaa olla suoritustehokkainta. Itse käyttäisin yhtä ohjelmointikieltä koko hommaan, enkä käyttäisi eri komentoja koska jokaiselle pitää antaa parametrit eri tavalla. Kun pysyy yhdessä kielessä, scriptiä on helpompi lukea.

Mitä nuo sortin kahvat ja parametrit on? Selvästi noissa on joku logiikka.
Kysymys on liian laaja. Tarkenna jos haluat tarkempia vastauksia.

Jos haluat ymmärtää juuri tämän koodin, katso
Koodia: [Valitse]
man sed
man sort
man cut

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #7 : 31.01.18 - klo:16.31 »
Englanninkieliset kuukausilyhenteet sortataan valitsimella -M, eli niitä ei muunneta numeerisiksi missään vaiheessa. Muut kentät sortataan numeerisesti.

Kappas, en lukenut niin tarkkaan. Mutta nyt kun toit tuon esiin, en ymmärrä miksi toi sed-komento tossa tarvitaan ollenkaan, kun kerran sortin tehdä voi tehdä käyttämällä aikaleiman osia suoraan. Vai missaanko taas jotain?

nm

  • Käyttäjä
  • Viestejä: 16246
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #8 : 31.01.18 - klo:16.51 »
Kappas, en lukenut niin tarkkaan. Mutta nyt kun toit tuon esiin, en ymmärrä miksi toi sed-komento tossa tarvitaan ollenkaan, kun kerran sortin tehdä voi tehdä käyttämällä aikaleiman osia suoraan. Vai missaanko taas jotain?

sortilla on vaikeaa poimia aikaleiman kenttiä, koska niitä ei ole eroteltu samoilla välimerkeillä. Lisäksi tuossa Apachen formaatissa aikaleiman edessä on muuta kamaa, joka voi sekoittaa asioita lisää. Säännöllisellä lausekkeella aikaleima on helpompi paikantaa luotettavasti.

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #9 : 01.02.18 - klo:22.37 »
Mitä nuo sortin kahvat ja parametrit on? Selvästi noissa on joku logiikka.

Koodia: [Valitse]
man sort
http://man7.org/linux/man-pages/man1/sort.1.html

Siinä määritellään sorttaus välilyönnillä erotetuille aikaleimakentille 1 (VVVV), 2 (KKK), 3 (PP), 4 (HH), 5 (MM) ja 6 (SS) eniten merkitsevästä vähiten merkitsevään. (Nuo kentät siis erotetaan ensin sedillä hakasulkujen sisältä eri kohdasta riviä ja kopioidaan rivin eteen eri järjestykseen.) Englanninkieliset kuukausilyhenteet sortataan valitsimella -M, eli niitä ei muunneta numeerisiksi missään vaiheessa. Muut kentät sortataan numeerisesti.

Sorttauksen jälkeen cut-komennolla leikataan lopusta alkuperäinen lokirivi sellaisenaan, eli tuloksena on alkuperäinen loki sortattuna aikajärjestykseen. Yleensähän lokitiedostot ovat jo aikajärjestyksessä, mutta tässä pyritään ilmeisesti ratkaisemaan tilanne, jossa useita lokitiedostoja on yhdistetty eri paikoista tai väärään aikajärjestykseen.


Itse käyttäisin tällaisiin hommiin Pythonia ja dateutil.parser -moduulia, joka lukee eri formaateissa olevia aikaleimoja ilman manuaalisia säätöjä. Apache-lokiparsereita ja vastaavia kyhäelmiä on toki Githubissa kymmenittäin tai sadoittain eri kielillä toteutettuna, jos tykkää käyttää valmista koodia.

Tämä oli se tärkein kohta näiden lausekkeiden suhteen:
Koodia: [Valitse]
KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position,
       where F is a field number and C a character position in the field;
       both are origin 1, and the stop position defaults to the line's end.
       If neither -t nor -b is in effect, characters in a field are counted
       from the beginning of the preceding whitespace.  OPTS is one or more
       single-letter ordering options [bdfgiMhnRrV], which override global
       ordering options for that key.  If no key is given, use the entire
       line as the key.  Use --debug to diagnose incorrect key usage.

En tosin vieläkään täysin näe yhteyttä tuon ja komentojen välillä. Ehkä joskus sitten.

nm

  • Käyttäjä
  • Viestejä: 16246
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #10 : 02.02.18 - klo:01.19 »
En tosin vieläkään täysin näe yhteyttä tuon ja komentojen välillä. Ehkä joskus sitten.

Alkuperäinen loki sisältää siis tällaisia rivejä:

Koodia: [Valitse]
127.0.0.1 - frank [10/Oct/2000:13:55:36 +0200] "GET /apache_pb.gif HTTP/1.0" 200 2326
sed-käsittely muovaa ne tällaisiksi:

Koodia: [Valitse]
2000 Oct 10 13 55 36 127.0.0.1 - frank [10/Oct/2000:13:55:36 +0200] "GET /apache_pb.gif HTTP/1.0" 200 2326
sort -k 1,1n poimii kultakin riviltä välilyönnillä erotetun kentän 1 (eli vuosiluvun 2000) numeerisessa muodossa (n) ensisijaiseksi järjestystekijäksi (koska se määritellään ensimmäisenä). Seuraava parametri -k 2,2M poimii kentän 2 seuraavaksi merkittävämmäksi järjestystekijäksi ja tulkitsee sen kuukauden lyhenteenä (M). Sitten kenttä 3 eli kuukauden päivä, 4: tunnit, 5: minuutit ja 6: sekunnit. Näin saadaan siis sortattua rivit oikeaan aikajärjestykseen.

Lopuksi cut-komennolla valitaan jokaisen rivin lopusta (kentästä 7 alkaen) alkuperäinen lokimerkintä.

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #11 : 02.02.18 - klo:09.36 »
En tiedä, että kumpi on kryptisempi:
Koodia: [Valitse]
sed -n -e "s/\(.*\[${S_PP}\/${S_KKK}\/${S_VVVV}:${S_HH}:${S_MM}:${S_SS} +[0-9]\{4\}\].*\)/\4 \3 \2 \5 \6 \7 \1/p" | sort -k 1,1n -k 2,2M -k 3,3n -k 4,4n -k 5,5n -k 6,6n | cut -d" " -f7-
vs.
Koodia: [Valitse]
KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position,
       where F is a field number and C a character position in the field;
       both are origin 1, and the stop position defaults to the line's end.
       If neither -t nor -b is in effect, characters in a field are counted
       from the beginning of the preceding whitespace.  OPTS is one or more
       single-letter ordering options [bdfgiMhnRrV], which override global
       ordering options for that key.  If no key is given, use the entire
       line as the key.  Use --debug to diagnose incorrect key usage.

Alkuperäinen loki sisältää siis tällaisia rivejä:

Koodia: [Valitse]
127.0.0.1 - frank [10/Oct/2000:13:55:36 +0200] "GET /apache_pb.gif HTTP/1.0" 200 2326
sed-käsittely muovaa ne tällaisiksi:

Koodia: [Valitse]
2000 Oct 10 13 55 36 127.0.0.1 - frank [10/Oct/2000:13:55:36 +0200] "GET /apache_pb.gif HTTP/1.0" 200 2326
sort -k 1,1n poimii kultakin riviltä välilyönnillä erotetun kentän 1 (eli vuosiluvun 2000) numeerisessa muodossa (n) ensisijaiseksi järjestystekijäksi (koska se määritellään ensimmäisenä). Seuraava parametri -k 2,2M poimii kentän 2 seuraavaksi merkittävämmäksi järjestystekijäksi ja tulkitsee sen kuukauden lyhenteenä (M). Sitten kenttä 3 eli kuukauden päivä, 4: tunnit, 5: minuutit ja 6: sekunnit. Näin saadaan siis sortattua rivit oikeaan aikajärjestykseen.

Lopuksi cut-komennolla valitaan jokaisen rivin lopusta (kentästä 7 alkaen) alkuperäinen lokimerkintä.

Tästä päätellen tuo jälkimmäinen luku on se järjestyksen määrittävä: 2,2M

Tuota sedin loppuosaa en myöskään hahmota. Kävisi järkeen jos olisi 6, mutta 7 esiintyy myös.
Koodia: [Valitse]
\4 \3 \2 \5 \6 \7 \1

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #12 : 02.02.18 - klo:10.37 »
Tuota sedin loppuosaa en myöskään hahmota. Kävisi järkeen jos olisi 6, mutta 7 esiintyy myös.
Koodia: [Valitse]
\4 \3 \2 \5 \6 \7 \1
4 : vuosi
3 : kuukausi
2 : päivä
5 : tunnit
6 : minuutit
7 : sekunnit
1 : IP-osoite

nm

  • Käyttäjä
  • Viestejä: 16246
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #13 : 02.02.18 - klo:13.17 »
Tästä päätellen tuo jälkimmäinen luku on se järjestyksen määrittävä: 2,2M

Ei vaan numerot määrittävät start ja stop positiot eli mitkä kentät otetaan järjestysperusteeksi. 2,2 valitsee järjestysperusteeksi kentät 2..2 eli kentän 2.
Esimerkiksi -k 1,3d valitsisi kentät 1, 2 ja 3 ja järjestäisi niiden yhdistelmää sanakirjajärjestykseen. Tuota voi  itse kokeilla esimerkkidatalla, niin ehkä pääsee paremmin jyvälle toimintalogiikasta.

Tuota sedin loppuosaa en myöskään hahmota. Kävisi järkeen jos olisi 6, mutta 7 esiintyy myös.
Koodia: [Valitse]
\4 \3 \2 \5 \6 \7 \1
4: vuosi
3: kuukausi
2: päivä
5: tunnit
6: minuutit
7: sekunnit
1: koko rivi (Tämä tulee siitä että säännöllisessä lausekkeessa on sulut koko muun lausekkeen ympärillä, ja lauseke kattaa koko rivin. Nämä sulut muodostavat ryhmän 1. Muut ryhmät tulevat aikaleiman osista.)
« Viimeksi muokattu: 02.02.18 - klo:13.18 kirjoittanut nm »

AimoE

  • Käyttäjä
  • Viestejä: 2718
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #14 : 02.02.18 - klo:13.26 »
1: koko rivi (Tämä tulee siitä että säännöllisessä lausekkeessa on sulut koko muun lausekkeen ympärillä, ja lauseke kattaa koko rivin. Nämä sulut muodostavat ryhmän 1. Muut ryhmät tulevat aikaleiman osista.)
Kiitos.

Tällä välin ehdin pohtia sitä että JA5Un hämmennys varmaankin liittyy siihen että sed-komennoss aviitataan numeroilla hakukenttiin ja sort-komennossa viitataan numeroilla lajitteluavainten kentiin, eikä näillä numeroilla ole mitään tekemistä keskenään koska kumpikin komento määrittelee kentät itsenäisesti, toisistaan riippuumatta. Juuri tästä syystä kehoitin heit aluksi hahmottamaan komennot erikseen. Kannattaisi ottaa koodi editoriin ja copy&pastella erottaa komennot ihan erilleen toisistaan niin ettei tällaista sotkeentumsita pääse tapahtumaan.

nm

  • Käyttäjä
  • Viestejä: 16246
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #15 : 02.02.18 - klo:13.42 »
Tällä välin ehdin pohtia sitä että JA5Un hämmennys varmaankin liittyy siihen että sed-komennoss aviitataan numeroilla hakukenttiin ja sort-komennossa viitataan numeroilla lajitteluavainten kentiin, eikä näillä numeroilla ole mitään tekemistä keskenään koska kumpikin komento määrittelee kentät itsenäisesti, toisistaan riippuumatta.

Jep. Tuossa yllä aiemmassa viestissä yritin esittää sanallisesti ja esimerkin avulla, mitä siinä tapahtuu.

JA5U

  • Käyttäjä
  • Viestejä: 462
    • Profiili
Vs: Bash-tulkkia paikalla
« Vastaus #16 : 03.02.18 - klo:14.27 »
Tällä välin ehdin pohtia sitä että JA5Un hämmennys varmaankin liittyy siihen että sed-komennoss aviitataan numeroilla hakukenttiin ja sort-komennossa viitataan numeroilla lajitteluavainten kentiin, eikä näillä numeroilla ole mitään tekemistä keskenään koska kumpikin komento määrittelee kentät itsenäisesti, toisistaan riippuumatta.

Jep. Tuossa yllä aiemmassa viestissä yritin esittää sanallisesti ja esimerkin avulla, mitä siinä tapahtuu.
No näinhän se oli.