Slide 1

Slide 1 text

͋ͳͨͷPHPΞϓϦɺϩά͸Ͱͯ·͔͢ʁ ͋Δ͍͸ϩάΛͩͯ͠·͔͢ʁ — PHPΧϯϑΝϨϯε෱Ԭ 2023 — 2023/06/24 — uzulla

Slide 2

Slide 2 text

ࣗݾ঺հ — ࠷ۙΞϝϦΧԣஅ͖ͯͨ͠uzullaͰ͢ — PHP͕ಘҙͳϑϦʔͷԿͰ΋԰Ͱ͢ άάͬͯ΋Β͑Ε͹ૣ͍ — PRαϙʔτ΍ϊϕϧςΟ੍࡞୅ߦͱ͔΋ͯ͠·͢ — ͓࢓ࣄ͓଴͓ͪͯ͠Γ·͢

Slide 3

Slide 3 text

DISCLAIMER — ҆қʹ͜ͷεϥΠυͷਅࣅΛ͢Δͳ — ·ͣɺݱ৔ͷઌୡ͕͜͏ͤΑͱݴ͑͹ै͑ — վֵ͸ɺνʔϜͰ߹ҙΛͱͬͯɺνʔϜͰ΍Ζ͏

Slide 4

Slide 4 text

վֵͱվળ — վֵͱ͸ɺطଘΛʮཪ੾Δʯ͜ͱ — վળͱ͸ɺطଘͷԆ௕Ͱྑ͘͢Δ͜ͱ — ·ͣ͸γεςϜͷվળΛߟ͑Δ — (ίʔυͰ͸ͳ͍ɺγεςϜશମ) — ৽نͷ࣌ʹ͸վֵ͠΍͍͢ — (ίϯϙʔωϯτ୯ҐͰ΋) — ࠓʮେྔʯʹ໰୊͕͋ΔͳΒɺ·ͣݮΒͯ͠ΈΑ͏ — തଧ͸શһͰૉפශʹͳΔ֮ޛΛ΋ͬͯ΍Ζ͏Ͷ

Slide 5

Slide 5 text

͓Ͷ͕͍ — γχΞ(ʁ)Ͱ͓Ջͳօ͞Μ͸ — ʮ͜Ε͸ಉҙʯ — ʮ͜Ε͸͋Γ͑Μʯ — ͱ͔͍ͩ͘͞ — एख͸൑அͰ͖ͳ͍

Slide 6

Slide 6 text

ࠓճͷωλόϨ ϩά͸ʮߦಈʯͱηοτͰ͋Δ

Slide 7

Slide 7 text

ϩάɺͬͯ͠·͔͢ʁ — ஌͍ͬͯΔਓʁ

Slide 8

Slide 8 text

ϩάྫ(Apache Access log) 127.0.0.1 - - [11/Jun/2023:10:30:15 +0000] "GET /index.html HTTP/1.1" 200 1234 — 127.0.0.1ɿϦϞʔτͷIPΞυϨε — -ɿϦϞʔτϢʔβʔ໊ʢແࢦఆ͸ϋΠϑϯͰஔ͖׵͑ΒΕΔʣ — -ɿϦϞʔτೝূϢʔβʔ໊ʢແࢦఆ͸ϋΠϑϯͰஔ͖׵͑ΒΕΔʣ — [11/Jun/2023:10:30:15 +0000]ɿΞΫηε͕ൃੜͨ͠೔࣌ɺܗ͕ࣜ࠷ѱʂ — "GET /index.html HTTP/1.1"ɿHTTPϝιουɺPATHɺϓϩτίϧͱόʔδϣϯ — 200ɿHTTPεςʔλείʔυ — 1234ɿϨεϙϯεͷαΠζʢόΠτʣ

Slide 9

Slide 9 text

ϩάͱ͍͑͹ΞΫηεϩά — ͳͥͳΒɺݹདྷ͸ඞͣ͋ͬͨ — ʮΤϥʔϩάʁग़ͳ͍͜ͱ΋ଟ͔ͬͨͳ(Ϩϯαό࣌୅Λࢥ͍ग़͠ͳ͕Β)ʯ — ʮ͜ΜͳϩάΈͨ͜ͱͳ͍ͳʯʮApacheͰ͢·Μʯ — ʮΞΫηεϩάͬͯϛυϧ΢ΣΞͰ͢ΑͶʯʮ͸͍ʯ — ࠷ۙ͸Google Analyticsͱ͔ͰݟΔ͠ɺ ຊ౰ʹࠔͬͨͱ͖͘Β͍͔͠ݟͳ͍͔΋ — ߏ଄Խ͞Ε͍ͯΔ͕ɺඪ४͸ͳ͍ — ApacheɺnginxɺPHPͷ-SͰҟͳΔ͠ɺେ఍ΧελϜͰ͖Δ — ͱ͍͏͔ɺApacheͷaccess logܗࣜ΋΄΅͔ͭΘΕͯͳͯ͘ɺCustomLogͷ combinedܗ͕ࣜී௨

Slide 10

Slide 10 text

Ͱɺϩάͱ͸ʁ — ͳΜΒ͔ͷΠϕϯτ࣌ʹ࢒͞ΕΔϝοηʔδ — ਓؒ΍ػց͕ಡΉͨΊʹ࢒͢ — ྺ࢙తʹςΩετͷ͜ͱ͕ଟ͍ — ͳΜ͔ͩΜͩҰߦͷ͜ͱ͕ଟ͍͕ɺGrep͠΍͍͔͢ΒͩΖ͏ — ߏ଄Խ͞Ε͍ͯΔ — ೔෇ͱ͔ɺIPͱ͔ɺUAͱ͔৭ʑͳϝλσʔλ — ύʔεͷͨΊʹJSONɺLTSVͳͲॲཧ͠΍͍͢΋ͷʹ͢Δ͜ͱ΋

Slide 11

Slide 11 text

ԿͰݟͯ·͢ʁ — ʮงғؾʯ — ϑΝΠϧΛcatɾtailɺgrep — Τεύʔɺ͋Δ͍͸ϩάͷ໛༷ — Slack௨஌ — ϩάϓϥοτϑΥʔϜ౳Ͱू໿ͯ͠ݕࡧ — ML/AIʹΑΔΞϊʔϚϦʔ௨஌

Slide 12

Slide 12 text

ͦΕ͸ࣗ෼Ͱͭͬͨ͘΋ͷͰ͔͢ʁ — ઌഐ͕ͭͬͨ͘ — ࣗ෼͕ͦ͏ͨ͠

Slide 13

Slide 13 text

ϩάɺΈͯ·͔͢ʁ — ݟͯΔਓɺखΛ͍͋͛ͯͩ͘͞

Slide 14

Slide 14 text

ʮΤϥʔϩάΈͯ·͔͢ʂʯ — Apache΍php-fpm͔Βग़ͯ͘Δ͍ΘΏΔΤϥʔϩά — ʮྫΛڍ͛ΔΑΓɺࣗࣾͷΤϥʔϩάΈͯΈ·͠ΐ͏ɺ॓୊ͳʂʂʂʯ ʮखൈ͖Ͱ͸ʁʯ — ઃܭɾίʔυ͕ؒҧͬͨΓɺDBʹ઀ଓͰ͖ͳ͔ͬͨΓ͢Δͱग़Δ΍ͭ — ಈ͔ͳ͍ͷͰɺϩάҎલʹؾͮ͘ — ʮಈ͍ͨɺϤγʂʂʯ=> ཪͰେྔͷNOTICE,WARN,STRICT,DEPRECATED — ͭ·Γɺݟͯͳ͍ਓ͸ࠓ͙͢൓লͯ͠΄͍͠ — PHPͷΤϥʔϩά͸ʮൃใଆʯͷϨϕϧௐ੔͕Ͱ͖ΔΘ͚Ͱ͸ͳ͍ͷͰɺࣺͯΒΕ͕ ͪ (ϨϕϧΛมߋ͢Δͱɺݟ͑ͳ͘ͳΔ) — (ࠓճͷओ୊Ͱ͸ͳ͍(͕ݴΘͣʹ͍ΒΕͳ͍ͷ͕PHPerͰ͋Δ)

Slide 15

Slide 15 text

PHPͷΤϥʔϩάͰͳ͍ϩά(΍΍͍͜͠) — ΍ͬͱͰ͕͢ɺࠓճ͸͜Εͷ࿩ʹͳΓ·͢ — ʮΤϯδχΞ͕ɺҙਤతʹग़͢ϩάʯ — ΞϓϦέʔγϣϯϩάɺ౳ͱݴΘΕΔ͜ͱ΋͋ΔΆ͍͕ਖ਼໊ࣜশΛ͠Βͳ͍ — (ͳ͓ɺFWͷΤϥʔϩά͸PHPͷΤϥʔϩάͱಉ͡Α͏ͳ૝ఆͰ͢)

Slide 16

Slide 16 text

࠶౓ͷΦν: ϩάઃܭ͸ΞΫγϣϯ͔Β͸͡ΊΑ — ʮͦͷϩάɺԿͷͨΊʹͰ͍ͯ·͔͢ʁʯ — ʮ͍ͭʯɺʮͲ͜Ͱʯɺʮͳʹ͕ʯɺ͸ଟ෼͋Γͦ͏ — ʮԿΛʯɺʮͲ͏͢Δ͔ʁʯ͸͖·ͬͯ·͔͢ʁ

Slide 17

Slide 17 text

ʮΤϥʔ͕ൃੜ͠·ͨ͠ʂʯ — …ͱ͍͏Τϥʔ(ਅإ) — স͍ͬͯΔ৔߹Ͱ͸ͳ͍Ͱ͢Αʁ — Ωϛ͸Έͨ͜ͱ͕͋Δ͔ʂʁ

Slide 18

Slide 18 text

Զ͸͋Δʂ͍ͬͯ͏͔ॻ͍ ͨ͜ͱ΋͋Δʂ ͩΕ΋͕͔͜͜Β࢝ΊΔͷ ͰͦΕ͸໰୊Ͱ͸ͳ͍ʂ

Slide 19

Slide 19 text

Ͱ͸ɺϩάͷྫΛ͔͍͜͠AI܅ʹͩͯ͠΋Β͍·ͨ͠ʂ — Failed to connect to the database server — Incorrect username or password — The requested resource could not be found — You do not have permission to access this resource — The user exceeded the rate limit for this resource

Slide 20

Slide 20 text

ԶͳΒApproveͤΜͧ — ʮThisͬͯͳʹʁɺThe userͬͯ୭ʁʯ — ରԠ͢ΔͨΊͷ৘ใ͕ͨΓͳ͍ — ϦΫΤετIDͱ͔ɺϩάΠϯϢʔβʔͱ͔ͦ͏͍͏ͷೖΕͨํ͕ྑ͍ - {ͳΜΒ͔ΞΠςϜ} could not be found - UID:234 does not have permission to access resource_id: abc - UID:123 exceeded the rate limit for resource: def — ͨͩ͠ɺେྔʹϩά͕Ͱ͓ͯΓɺͦΕͷू໿Λ͍ͯ͠Δ৔߹͸രൃతʹ૿͑Δ͜ͱ͕͋Δ (·͋ɺͦΕ͸ઌʹ௚ͨ͠ํ͕ྑ͍ͷͰ͸…)

Slide 21

Slide 21 text

ϙΠϯτ ίϯςΩετΛࣺͯΔͳ

Slide 22

Slide 22 text

ʮͦͷͱ͖Ͳ͏͔ͩͬͨʯ — ࠶ݱ΍ௐ͕ࠪͰ͖·͔͢ʁ — ʮ୭͕ӨڹΛड͚͔ͨϩάΛΈ͍ͯͩ͘͞ʯʮͦ͜ʹͳ͚Ε͹ͳ͍Ͱ͢Ͷʯ — ʮ࠶ൃ͸͠·ͤΜ͔ʁʯʮࢁצͰͳ͓ͨ͠ͷͰ࣍Λ଴ͪ·͠ΐ͏ʯ — ͋Δ͚ͩग़ͤ͹ྑ͍Θ͚Ͱ΋ͳ͍ɻಡΈͮΒ͍͠ɺݸਓ৘ใ΋͋Δ͠ɺDisk΋͋;ΕΔ ͠ — ࢲʮ͕Μ͹Εɺͳ͓༗ঈͰ૬ஊʹ͸ͷΕ·͢ʯ

Slide 23

Slide 23 text

ͦͯ͠ɺ๨ΕͣʹΞΫγϣϯʹͭͳ͛Ζʂ — ʮ͜͏ͯ͠΄͍͠ͳʯͱࢥͬͯ΋ɺॻ͔ͳ͍ͱ·ͣͭͨΘΒͳ͍ — ʮյΕͨϑΝΠϧΛফͤʯͱ͔ϩάʹॻ͍͓ͯ͘·Ͱ͋Δ — खॱॻ΍όάνέ౳ͱͭͳ͕͍ͬͯΔ͜ͱ͕๬·͍͠ — ͳ͓ɺURL͸มΘΔͷͰɺݕࡧ༻ʹIDʹ͢Δํ͕ྑ͍ — ID͸࿈൪΍UUID͕ྑ͍ — ҙຯΛ΋ͨͤΔͷ͸ݸਓతʹΞϯνύλʔϯ — (ϦϑΝΫλ͠ʹ͘͘ͳΔ) — …͕ɺͳ͔ͥΈΜͳIDʹҙຯΛ͕࣋ͨͤͨΔ͠…·͋΍ͬͯΈͯ΋͍͍ͷͰ͸… — Զ͸͓קΊ͠ͳ͍͚Ͳͳʂʂ

Slide 24

Slide 24 text

> Error: Error ͳʹ͕Τϥʔͳͷʁʁʁ > Error: User Information update. …Ͳ͜Ͱʁ୭͕ʁ > Error: User update fail. user_id: 1 ͏ʔΜ…͜ͷϝοηʔδ͸ɺͲ͜ͷ৔ॴ͚ͩͬͳ…શจݕࡧ͠Α͏͔…ʁ·͋໘౗͔ͩΒΈͳ͔ͬͨ͜ͱʹ͢Δ͔ʁ > Error: User update fail. user_id: 1 on /path/to/Some.php:123 ;ʔΜɺ͜ͷϑΝΠϧ͔…ͳΜͱͳ͘Θ͔Γͦ͏ͩͳ…Ͱ΋·͋ݟͳ͔ͬͨ͜ͱʹ͍͍ͯ͠ͷ͔Θ͔ΒΜͳ > Emerg: Update user order record fail. user_id: 1 on /path/to/Some.php:123 Emergʁͬͯ͜ͱ͸க໋తΤϥʔ͔ʂͩΕ͔͜ΕͲ͏͢Ε͹͍͍͔ͬͯ͠ΔʁͱΓ͋͑ͣίʔυಡΜͰௐࠪ͢Δ͔…ʂ > Emerg: Update user order record fail. user_id: 1 on /path/to/Some.php:123 see OpDoc:ABC123 க໋తΤϥʔͩʂDocΈͯΈΑ͏ʂ…ͳΔ΄Ͳ·ͣCR͞Μʹ࿈བྷ͔ɺϢʔβʔ͠Β΂ͯୈҰใʂͦͷޙӡ༻ͰΧόʔ͔ʂ

Slide 25

Slide 25 text

ʮ͋Εʁ͜Ε͸؂ࢹͰ͸ʁʯʮͦ͏Ͱ͢ʯ — ٯʹɺ؂ࢹ͕ແ͍ͳΒϩά͸ԿͷͨΊʹʁ — (؂ࢹʹ͸ɺࣄޙͷௐࠪ΋ؚΊ·͢) — ੋඇ؂ࢹͷॻ੶ΛಡΉͱྑ͍ͱࢥ͍·͢ɺࠓճ͸؂ࢹʹ͍ͭͯ͸ਂ۷Γ͸͠ͳ͍

Slide 26

Slide 26 text

͞ΒͳΔయܕతͳίϯςΩετɾϝλσʔλ — ϑΝΠϧͱߦ൪߸ɺελοΫτϨʔε͸౰વ͓໾ཱͪ৘ใ — ઈରʹඞཁͳ΋ͷ͸ϩΨʔͷϋϯυϥͰࣗಈతʹೖΕΔͷ΋ྑ͍ — ϩΨʔͰϩάϝοηʔδΛՃ޻͠ɺఆܗͰೖΕΔͳͲ — ϋϯυϥʹ͍ͭͯ͸ɺmonologͷυΩϡϝϯτ΍ɺ͓͗͞ΜͷτʔΫΛݟ͍ͯͩ͘͞ — ࠷ۙ͸NewRelicͱ͔DataDogͱ͔ͷAPM͍ΕͯΔͱࣗಈతʹूΊͯ͘ΕΔɺศརʂ — ຊ౰ʹศརͳͷͰɺૉ௚ʹۚΛ෷ͬͯߦ͘ͷ͕ྑ͍ͱࢥ͍·͢ɻ — ϙϯʂͱͰͨΤϥʔʹͦ͏͍ͬͨίϯςΩετ͕ࣗಈͰ͍ͭͯ͘ΕΔɺ࠷ߴ

Slide 27

Slide 27 text

ΞΫγϣϯ͕͖·ΔͱɺϩάϨϕϧ͕ܾ·Δ − ී௨ͷϩΨʔ͸ϩάϨϕϧΛ࣋ͭ - DEBUG - INFO - NOTICE - WARNING - ERROR - CRITICAL - ALERT - EMERGENCY

Slide 28

Slide 28 text

Ϩϕϧ͸ΞΫγϣϯ࣌ͷτϦΞʔδͰ͋Δ — ۓٸɺଈԠɺܦա؍࡯ɺͲ͏Ͱ΋͍͍ɺ։ൃ༻ͱ͔ — ·͋σϑΥϧτ͸ΤϥʔͰ͢ΑͶɺͳ͔ͥ͠ΒΜ͕ɻ — ͜Ε͕੔උ͞Ε͍ͯͳ͍ͱແࢹʹͭͳ͕Δ — શ෦͕Errorͩͱ… ʮͳΜ͔ΤϥʔͰͯ·͚͢Ͳ…ʁʯ ʮ͋ͬ͜ͷΤϥʔ͸ແࢹ͍͍ͯ͠ΤϥʔͳΜͰʯ ʮ͔ͦͬʙʙ(ͦΜͳ͜ͱΘ͔Δ͔ʂೋ౓ͱݟͳ͍Θʂ)ʯ — ͋ͳ͔ͨ͠ղΒͳ͍ͱɺपΓ͸αϙʔτͰ͖ͳ͍ — ʮ͜Ε͸ଈԠ͕ඞཁͰͨ͠ʂͳΜͰແࢹͨ͠ΜͰ͔͢ʂʯ ʮ͠ΒΜ͕ͳ(͋͋ʂ͢Έ·ͤΜͰͨ͠ʂࠓޙؾΛ͚ͭ·͢ʂ)ʯ

Slide 29

Slide 29 text

ϩάϨϕϧ͸ͪΌΜͱ͚ͭ Α͏ͳʂ ҰਓͰ։ൃɺӡ༻ɺ24/365 ରԠ͢ΔͳΒϤγʂʂ

Slide 30

Slide 30 text

ͱ͸͍͑Ή͔͍ͣ͠ɺԹ౓͕ࠩ͋Δ — νʔϜͰ߹ҙΛऔΔඞཁ͕͋Δ — ྫ:ʮਂ໷ʹ͖ͨͨى͜͞ΕΔ΂͖͔ʁʯσʔλ͕յΕଓ͚Δʁ — ྫ:ʮ࣍ͷӦۀ೔Ͱྑ͍ʯӨڹൣғ͕޿͕Δʁ — ྫ:ʮϦτϥΠͰ௚ΔʯਓؒͷରԠ͕…ඞཁɾෆཁʁ — ͜͏͍͏ͷΛɺ૝૾ͯ͠ϩάϨϕϧʹϚοϓͯ͠Թ౓ײΛܾΊΔ — ͜ͷ͋ͨΓ͸ޙͰ΋ม͑ΒΕΔ — ϩάϨϕϧͷ෼ྨΛޙͰม͑Δͷ͸େม͕ͩɺ ϩάϨϕϧʹରԠ͢Δߦಈ͸ม͑΍͍͢ — ͱΓ͋͑ͣ৭ʑߟ͑ͯΈͯ΄͍͠

Slide 31

Slide 31 text

Ͱɺϩάͷൃใ(ൃੜ)͸Ͳ͜Ͱ͢Δʁ — جຊతʹ͸ɺ(͍ΘΏΔ)ίϯτϩʔϥ΍υϝΠϯ૚Ͱൃੜͤ͞Δ΂͖ͩͱʮࢲ͸ʯࢥ͏ — ͦΕ͕ʮͲ͏ѻΘΕΔ͔ʯ൑அͰ͖Δ૚ — ࢀরϖʔδͷDBΫΤϦࣦഊͱ͔Ͳ͏Ͱ΋Α͍͕ɺ ܾࡁͷDBΫΤϦࣦഊ͸Ϡό͍ͳͲ͋Δ — ϥΠϒϥϦ΍ϨϙδτϦ૚ͱ͔Ԟਂ͘Ͱ΍Δͱ΍΍͍͜͠ — ʮϩΨʔΛҾ਺Ͱύεͯ͠ߦ͚Δൣғʯ͕ແ೉ͱࢥ͏ — ϥΠϒϥϦ౳Ͱ͸ΤϥʔͳΒྫ֎Λͳ͛ɺ্Ґʹ೚ͤͨํ͕ྑ͍ — ͦͷͨΊʹ΋ಠࣗྫ֎ͱ͔ॻ͜͏ — ʮྫ֎͸ݏ͍ͳΜͰ͢Αʯ ʮ͡Ό͍͍͋Τϥʔදݱํ๏͓͑ͯ͘͠Εɺ-1ฦ͢ͱ͔͸ແ͠ͳʂʯ

Slide 32

Slide 32 text

۩ମతͳϩΨʔ(ϩάΛൃੜͤ͞Δ΋ͷ)ʹ͍ͭͯ — جຊ͸monologɺσϑΝΫτελϯμʔυ — monolog͸֦ுੑ͕ߴ͍ — ϓϩηοαɺϋϯυϥɺϑΥʔϚολΛొ࿥ɾࣗ࡞Ͱ͖Δ — Ճ޻ɺϝλσʔλऩू෇༩ɺૹ৴(อଘ)ͳͲ͕ࣗ༝ʹ — ͜ͷޙͷ͓͗͞ΜͷτʔΫΛΈͯ͘Ε — ϩΨʔ͸ෳ਺࡞ΕΔ — ͜ͷϨϕϧҎԼ͸ແࢹ͢ΔϩΨʔ — ͜ͷϨϕϧͳΒSlackʹඈ͹͢ϩΨʔ — ౳ — ·͋ɺ࠷ڧͰ͢ɻߟ͑Δ͘Β͍ͳΒmonologͰ

Slide 33

Slide 33 text

Slack௨஌ྫ // ϩΨʔΛ࡞੒ $log = new Logger('slack_logger'); // ϑΝΠϧϋϯυϥΛ௥Ճ $log->pushHandler(new StreamHandler('/path/to/log')); // SlackϋϯυϥΛ௥ՃʢϩάϨϕϧ͕ΫϦςΟΧϧͷ৔߹ͷΈʣ $log->pushHandler(new SlackWebhookHandler($slackWebhookUrl), Logger::CRITICAL); // ϩάϝοηʔδΛه࿥ $log->error('Slackʹඈ͹ͳ͍'); $log->critical('SlackʹඈͿ');

Slide 34

Slide 34 text

ϩΨʔ͸ෳ਺ੜ੒͞ΕΔલఏʹ — ʮελςΟοΫʹίʔϧ͢Δͱศརʂʯ͸Ξϯνύλʔϯ — UnitTestͰʮ͜͜Ͱ͸null ϩΨʔʯͱ͔͍ͨ͠ — Feature Flagͱ૬ੑ΋Α͍ — ϦϦʔε௚ޙɺ͜ͷػೳ͚ͩϩάϨϕϧ͸ม͍͑ͨͱ͔͋Δ — ίʔυͷԞਂ͘ͰϩάϨϕϧΛIF෼ذ͢Δͷ͸ਖ਼ؾͰ͸ͳ͘ɺFeature୯ҐͰϨϕϧΛม ͑ͨϩΨʔΛInjectͰ͖ͨ΄͏͕ศར — ࠷ѱɺϝοηʔδʹPrefixͱ͔ɺಠࣗϩάϨϕϧͱ͔ɺϋϯυϥͰվมͱ͔΋͋Δ ͕ɺ͏ʔΜ… — ϩΨʔࣗମΛࠩ͠ସ͑ͨ΄͏͕Ͳ͏ߟ͑ͯ΋҆શ

Slide 35

Slide 35 text

class SomeFeature{ public function __construct(Logger $logger){} public function run(); } // == in prod $log = new Logger('slack_logger'); $log->pushHandler(new StreamHandler('path/to/log')); $log->pushHandler(new SlackWebhookHandler($slackWebhookUrl)); $some = new SomeFeature($log); // SlackͱϑΝΠϧʹอଘ // == in tests $log = new Logger('null_logger'); $log->pushHandler(new NullHandler()); $some = new SomeFeature($log); // ڏۭʹফ͑Δ

Slide 36

Slide 36 text

ϩά͸ΠϕϯτͰ͋ΓɺଟॏͳετϦʔϜ — ϩά͸Πϕϯτ(Ϩίʔυ)Ͱ͋ΓɺʮҰߦͷςΩετʯͰ͸ͳ͍ — SourceͱFilterͱSinkΛߟ͑Δ — Source͸ൃใɺ͜͜·Ͱઆ໌ͨ͠ͱ͓Γ — Filter͸ࣗಈతʹ೔෇͍ΕͨΓɺ੔ܗͨ͠ΓɺJSONʹͨ͠Γ — Sink͸ϑΝΠϧͩͬͨΓɺసૹͩͬͨΓɺ௨஌ͩͬͨΓ — ଟஈɾଟॏʹͰ͖Δ — monologͷத͚ͩͰͳ͘ɺେମͷϩάج൫͸ͦ͏͍ͬͨ֓೦͕͋Δ(΋ͬͱߴ౓͚ͩ Ͳɺ·͋جຊతͳߟ͑ํͱͯ͠) — ͜ͷ͋ͨΓ͸͜ͷޙͷ͓͗͞ΜͷτʔΫΛݟ͍ͯͩ͘͞ — ʮMonologͷ࣮૷ʹֶͿInterfaceͷ࢖͍Ͳ͜Ζʯ

Slide 37

Slide 37 text

// == ͋ΔPHPͷத… +-------------+ | Source | +-------------+ | v +-------------+ | Filter | +-------------+ | v +-------------+ | Sink | +-------------+

Slide 38

Slide 38 text

// == ͋ΔPHPͷத… +-------------+ | Source | +-------------+ | v +-------------+ | Filter | +-------------+ | v +-------------+ | Sink | +-------------+ | // == ͔͜͜Βɺผͷϩάج൫΁… v +-------------+ | Source | +-------------+ | v +-------------+ | Filter | +-------------+ | v +-------------+ | Sink | +-------------+

Slide 39

Slide 39 text

(লུ) | v +-------------+ | Sink | +-------------+ | // == ෼ذ΍ίϐʔ(ෳ੡ͷૹ৴)΋͋ΔΑʂ ├----------------------┐ v v +-------------+ +-------------+ | Source | | Source | +-------------+ +-------------+ | | v v +-------------+ +-------------+ (লུ)

Slide 40

Slide 40 text

ΰουϩΨʔ໰୊ — ϑϥΫλϧ(ೖΕࢠ)ͳߟ͑ํΛͤͣɺ۪௚ʹίʔυΛॻ͘ͱ஍ࠈͰ͢ — ʮͳΜͰͦΜͳந৅తͳ͜ͱΛ͠ͳ͍ͱ͍͚ͳ͍ͷʁ͜͜ʹSlackʹૹ৴͔͚ͬͯ͹͍͍ ͡ΌΜʯʮͦ͏͢Δͱͳɺෛ࠴Λະདྷʹ͓͘Δ͜ͱʹͳΔΜ͡Όʯ — (୹ظతʹͦ͏͢Δͱ͔ɺϨΨγʔίʔυ͔ͩΒ͔ͨ͠ͳ͘͸Θ͔Δ͕ɺ৽نͰ͸Ϡό ͍) — ৼΔ෣͍Λਂ͘ʹॻ͖ࠐΉͳʂ — ʮ͜͜ͷΤϥʔ͸Slack௨஌͍ͨ͠ʯΛϋʔυίʔυͯ͠͸μϝ — ʮ͜Ε͸ΫϦςΟΧϧʯ(Source)=>ʮΫϦςΟΧϧ͸Slack΁ʯ(sink)ͱ͍ͨ͠ — ͪΌΜͱؔ৺Λ෼཭͠Α͏ͳ

Slide 41

Slide 41 text

ͦ΋ͦ΋ू໿͠ͳ͍ͱ΍ͬͯΒΕͳ͍ΜͩΑʂ — ݱ୅͸ϗετ͕ෳ਺͋Δ͠…ू໿͠ͳ͍ͱ͖͍ͭͰ͠ΐৗࣝతʹߟ͑ͯ… — ϩά؅ཧɾղੳج൫Λ׆༻ͤΑ — FluentdͰNewRelicʹ͓͘Δͱ͔ stderrΛCloudWatch Logsʹ͓͘Γ͜ΜͰͱ͔ — ֎෦Խ͢Δ͜ͱͰؾܰʹมߋͰ͖Δ͠ɺσϓϩΠແ͠ʹௐ੔΋Ͱ͖Δ

Slide 42

Slide 42 text

༨ஊ — ࢲʮίϯϑΟάͬͯͱ͜ΖʹεοͱṖͷσϑΥϧτ͕ઃఆ͞Ε͍ͯͯɺͦΕ͕ਆͷ͓ݴ༿ ͔ͩΒௐ੔͍ͯ͠ͳ͍ɺͱ͍͏Α͏ͳݱ৔ͰDisk fullԿ౓΋ݟͨɻ࠷ѱʂʂʯ — ͪΌ·΄ΓʮͦΕ͸LaravelΛͪΌΜͱ࢖͑ͳ͍ਓ͕ѱ͍Ͱ͢Αʯ — Laravelϓϩͷ໊ݴͰ͢ — ϩά͸ن໛ʹൺྫ͢Δ͠ɺͪΌΜͱઃఆ͢Δඞཁ͕͋ΓɺLaravel͸σϑΥϧτͩͱ monologΛ΄ͱΜͲௐڭͯ͠ͳ͍ͷͰΈͳ͞Μ͕ͪΌΜͱͯ͋͛͠Δඞཁ͕͋Δ͔Β Ͷʁʁʁ — (શ͍ͬͯ͘͡ͳ͍ͷʹແࣄͳͷ͸ɺଟ෼τϥώοΫ͕ແ͍͔ΒͳͷͰɺૣΊʹରԠͯ͠ ͓͜͏ͳʂ)

Slide 43

Slide 43 text

'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['single'], ], 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ],

Slide 44

Slide 44 text

ϩάͷΑ͋͘Δ᠘ — ʮ͍ΕΕ͹͍ΕΔ΄Ͳ௥͍͔͚΍͍͢ʂʯ — => ͋Δҙຯͦ͏͕ͩɺϊΠζ͕૿͑Δ ϩά͕؂ࢹͱ࿈ܞ͢Δ͔Βʹ͸΄Ͳ΄Ͳ͕ྑ͍ ϩάϨϕϧͱ૊Έ߹Θͤͯߟ͑ͯ — ʮϑΝαʔυ΍ελςΟοΫϝιουͰͲ͔͜ΒͰ΋ݺ΂ͯศརʂʯํࣜ — => কདྷతʹ͸(େ఍)ͭΒ͍ͷͰɺςετ΍ϨΨγʔίʔυҎ֎Ͱ͸΍Ίͨํ͕ྑ͍ (ςετͰϩάʁʁʁ) — ʮDI͸ʁʯʮDIͰ࡞ΔϨϕϧͳΒ…͍΍…͔͠͠…ʯ — =>ϩΨʔ͕Ұຊ͔͠ͳͯ͘ྑ͍ͳΒྑ͍ͷͰ͸ (΋ͪΖΜɺ΍Ε͹ෳ਺࡞Δ͜ͱ͸Ͱ͖ΔͩΖ͏ɺؾΛ͚ͭͯ࢖͍ͬͯͬͯ͘Ε)

Slide 45

Slide 45 text

༨ஊ — ྫ֎͠ʹ͍͘ॴͬͯ͋ΔΑͶ… — ExcepionΛฦͬͯ͢Ͳ͏Ͱ͔͢ʁҟ୺Ͱ͔͢Ͷʁ function getSome(): Some|null|Exception {} — ʮ࢖ͬͯΔΜͰ͔͢ʁʯʮ໧ൿ͠·͢ʯ

Slide 46

Slide 46 text

ͱ͜ΖͰɺόον͸ʁ — جຊ͸ಉ༷͕ͩɺͦͷ্ͰUNIXͷCLIϓϩάϥϜͷྲّྀʹ৐ͬऔΔ΂͖ — εςʔλείʔυ͸ΩνϯͱͤΑ — CronͷྲّྀʹଇΔͳͲ — ʮΤϥʔͰͳ͍ͳΒɺԿ΋ग़͞ͳ͍ʯ — PHPͷΤϥʔϩάͷग़ྗઌΛϩάϑΝΠϧʹ͢Δͱը໘ʹͰͣɺؾ͔ͮͳ͍͜ͱ͕͋Δ ٯʹɺSTDERRʹͩ͢ͱɺϩάͷసૹ͕໘౗ͳ͜ͱ΋͋Δ — monologͷग़ྗϋϯυϥ͸ࣗ༝ʹελοΫͰ͖ΔͷͰศར — ϩάϑΝΠϧʹͩͭͭ͠ɺSTDERRʹग़͢ͱ͔΋Ͱ͖Δ — ͦ΋ͦ΋ʮCLIϓϩάϥϜʯͳͷ͔ͩΒɺPHPࣗମͰ͕Μ͹Βͳ͍ͷ΋खɺී௨ͷCLIͱ ͯ͠ॻ͖ɺjournald(syslog+cron),fluentd(౳)ͳͲͷ૊Έ߹Θͤ

Slide 47

Slide 47 text

ͰʂϩάΛΈͯ·͔͢ʁ — ࣮͸৭ʑݟΔʮ֯౓ʯ͕͋Δ — ଈԠ͢Δϩά — ࣌ܥྻɾ࣌ؒൣғͰݟΔϩά — ͨΊͯɺΧ΢ϯτղੳ͢Δϩά — ͞ΒʹͦΕͷෳ߹…

Slide 48

Slide 48 text

ଈԠɺΞϥʔτ — ͙͢͞·֬ೝɾ௚͞ͳ͍ͱ͍͚ͳ͍Τϥʔ — લఏͱͯ͠ɺͩΕ΋Τϥʔϩά͸Έͳ͍ͷͰ͋Δʂ(ਅإ) — ۤ৘͕དྷͯɺݟΔ — ͦΜͳ͜ͱͰΑ͍ͷͩΖ͏͔ɺ͍΍ɺΑ͘ͳ͍ͩΖ͏ — ͭ·Γɺʮϩά͕དྷ͍ʯͷ࣌୅ — ϝʔϧ͢ΔɺSlackʹ౤͛ΔɺPagerDutyͱ͔͔ͭ͏ — ϩάϓϥοτϑΥʔϜ΍monologͷϋϯυϥΛ࢖͏ — ݟͨ͋ͱɺΞΫγϣϯΛ͠·͠ΐ͏ — Կ΋͠ͳ͍ϩάͳΒফ͢ɻͰͳ͍ͱ͞ΒʹΑ·Εͳ͘ͳΔ

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

࣌ܥྻɾ࣌ؒൣғͰݟΔϩά — ϩάϓϥοτϑΥʔϜΛ͔ͭ͏ͷ͕ఆ൪ — NඵؒʹMճΞϥʔτ͕͕͋ͬͨΒͲ͏ߟ͑ͯ΋͓͔͍͠ — ʮͨ·ͨ·ࣦഊ(ِཅੑ)ʯ͸ଟ͍ͷͰɺ࿈ଓNճͰʙͱ͍͏৚͕݅΄͍͠ࣄ͸ଟ͍ — ͕ɺηϧϑώʔϧ͢Δ΋ͷ͸௨஌͢Δඞཁͳ͍ — NewRelicͩͱɺNRQLͳͲͰࣜΛఆٛͰ͖Δ => ৚݅ͷᮢ஋Λ͑ͨ͜ΒΞϥʔτ — ࣗલͰ࡞Δࣄ΋Ͱ͖Δ͕ɺSaaSΛ͔ͭͬͨ΄͏͕ૣ͍ — FluentdͳͲϩάసૹͳͲͷઃఆ͕ඞཁ(ͳ৔߹΋)

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

ͨΊͯɺ෼ੳ — ҟৗऴྃͷΤϥʔ͸र͏ͷ͕؆୯ͩΖ͏(ग़ͳ͍ʁग़ͦ͏ʂ) — ʮਖ਼ৗऴྃ͠·͕ͨ͠ͳ͍ʯ͜ͱ͸؂ࢹͰ͖Δ͔ʁ — ʮ։࢝͠·ͨ͠ʯͱ͔ϩά͍Βͳ͘Ͷ͑ʁ͓ͬͯ΋͏(ओ؍)͚ͲɺͪΌΜͱಈ͍͍ͯΔ͔ Ͳ͏͔஌Γ͍ͨ(ຊؾͰͦ͏ࢥͬͯΔ)ͳΒඞཁ͔΋ — ͜͏͍͏ͷ͸ϩάϓϥοτϑΥʔϜΛ࢖Θͳ͍ͱ؂ࢹɾूܭͰ͖ͳ͍ — ࣮ߦ࣌ؒͱ͔΋ɺूܭͰ͖Ε͹ҙຯ͋ΔΑͶ — Ͱ΋͜Ε͸ϊΠδʔʹͳΓ͕ͪɺϩάϨϕϧ͸͛͞Α͏ɻ

Slide 54

Slide 54 text

μογϡϘʔυԽ — ͞Βʹɺݟ͑ํΛม͑ͯΈΔͳͲ͕͋Δ — ϝτϦΫεʹͯ͠ΈΔɺʮ೏͍ʯΛײ͡Δ — ͋ΔσϓϩΠΛڥʹͯ͠૿͑ͨͱ͔ — ͜Ε͸ϩάج൫΍ɺूܭͷγεςϜ͕ඞཁͰɺԿ౓΋ݴ͏͚ͲࣗલͰ΍Δͷ͸ͩΔ͍ — ͜ͷ͋ͨΓ͸؂ࢹͷ͸ͳ͠ʹͳΔͷͰɺࠓճ͸ྦͷׂѪ

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

·ͱΊ — ʮϩά͸ɺԿ͔Λ͢ΔͨΊʯɺͦ͏͍͏ൃ૝Ͱॻ͜͏ — ͱ͍ͬͯ΋ɺਓؒ͸ϩάΛݟͳ͍ͷͰʮϩά͕དྷ͍ʯͷ࣌୅ — ͦ͏͢Δͱɺ৭ʑͳ΋ͷ͕ੜ͖ͯ͘Δ — ϩΨʔղੳɺϩά؅ཧπʔϧɺΞάϦήʔλΛ׆༻͢Δͱߴ౓ͳ͜ͱͰ͖Δ — (࠷ѱɺmonolog͚ͩͰ΋৭ʑͰ͖Δ) — ྑ͍ϩάઃܭͯ͠ɺྑ͍ӡ༻͍ͯ͜͠͏ͳʂʂ