ã¯ããã« mediba Advent Calendar 2022 ãšã New Relic Advent Calendar 2022 ã®8æ¥ç®ã®èšäºãšãªããŸãã ã¿ãªããNew Relicã§ã¢ã©ãŒãèšå®ããŠããŸãã? ãã¯ãããããã£ãª!medibaã§SREãããŠããåæµŠïŒ @kitta0108 ïŒã§ãã ä»åã¯New Relicã§ãªã³ã³ãŒã«å¯Ÿå¿ãåããšããéç¥æ©èœãéçšã«å®è£
ããããšããéã«ã ãäžè©±ã«ãªãã§ãããAlertæ©èœã®äžã§ãæéã«ãŸã€ããèšå®å€ã®è©±ãã€ãã€ããšæžããŠãããŸãã åŒç€Ÿã®äžã§ãããã®èšå®å€ã¯1ã€ãã€çŽè§£ããŠããã®ãå°é£ã§ããããªããšãã声ãå€ãããã£ãŠããã®ã§ãçããšã£ãŠã¿ãŸããã ãšããããã§ããã®âæéâãæå®ããèšå®ã«ã€ããŠã - ãªãå¿
èŠãªã®ã - ã©ããªæã«ãã¥ãŒãã³ã°ããã®ã - äžæŠã¯äœãèããã«èšå®ããããšãã¯ã©ããããããã®ã ã玹ä»ããŠãããŸãã èªè
æ³å® ãããªæ¹ã
ãžäœãããã®è²¢ç®ãã§ããèšäºã«ãªãããæèããŠããŸãã New Relicã§ã¢ã©ãŒãèšå®ããããã¢ãããŒã·ã§ã³ããã ã¡ããªã¯ã¹ã®æ±ãã«èªä¿¡ããªã ä»ãŸã§ãªããšãªãã¢ã©ãŒãèšå®ããŠããã®ã§çè§£ãæ·±ããã åé¡ã®èšå®å€ æéãèšå®ããå€ã£ãŠ5ã€ããããã§ããããŒã ä»åã¯ä»¥äžã解説ããŠãããŸãã Condition thresholds Signal loss expiration time Window Duration Slide by Interval Event flowã®DelayãŸãã¯ãEvent Timerã®Timer ãé¡ è§£èª¬ã®äŸ¿å®äžã以äžã2ã€ã®äŸã䜿ã£ãŠãããŸãã - äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) SELECT max(aws.applicationelb.HealthyHostCount) FROM Metric FACET aws.applicationelb.LoadBalancer - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) SELECT sum(aws.applicationelb.HTTPCode_Target_5XX_Count) FROM Metric FACET aws.applicationelb.LoadBalancer 1.Condition thresholds ã¢ã©ãŒãã®éŸå€ãšããŠã®æéæå®ã§ãã äŸãã°ã above or equals 2 at least once in 1 minutes ãšæå®ããå Žåã¯ã å°ãªããšã1åéã«æå®ã®ã¡ããªã¯ã¹ã2以äžã«äžãã£ãæã ã¢ã©ãŒãå€å®ãšããèšå®ã§ãã ã¢ã©ãŒããšããŠãã¡ããªã¯ã¹ãèŠã«ããé »åºŠïŒåæ°ïŒãšããèŠæ¹ãã§ããŸãã ãã®æéã¯ãçãããã°ããã»ã©ã ããŸãã«ã¡ããªã¯ã¹ãäžãã£ãŠãªããèŠãŠãããã®ã§ã è§£å床ãé«ããããšãã§ããŸãã - äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) equals 0 at least once in 1 minutes 0ã«ãªã£ããã¢ã©ãŒããªã®ã§ãequals 0ãšæå®ããŸãã é »åºŠã«é¢ããŠã¯ã0ãšãªã£ãæã«ããé£çµ¡ã欲ããã®ã§ã1å鿝ã«ããŸãã - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) above or equals 10 at least once in 5 minutes 10以äžã«ãªã£ããã¢ã©ãŒããªã®ã§ãabove or equals 10ãšæå®ããŸãã é »åºŠã«é¢ããŠã¯ã5åéã®ç·éãå€å®ããããã®ã§ã5忝ã«ããŸãã 2.Signal loss expiration time ã¡ããªã¯ã¹ãNew Relicã§åä¿¡ã§ããªãã£ããšãã«ã Signal lossãšå€å®ããããŸã§ã®æéã§ãã - äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) ALBã®HealtyHostCountã¡ããªã¯ã¹ã¯ 1åéã«1åã®é »åºŠã§éèšãããã¡ããªã¯ã¹ãªã®ã§ã AWSããNew Relicã«å¯ŸããŠã¯ã以äžã®ããã«1åéã«1åã®ããŒã¹ã§ã¡ããªã¯ã¹ããŒã¿ãéãããŸãã ãããããã®ã¡ããªã¯ã¹ããŒã¿ããããã¯ãŒã¯ã®æºãããªã©ã®åå ã«ããã New Relicã«3åéå±ããªãã£ããšããŸãã ãã®ãããªã±ãŒã¹ã«ãããŠãã¢ã©ãŒããšããŠã©ã®ãããªæ¯ãèããããã¹ããã å³å¯ãªèšå®ãå¯èœã§ãã HealtyHostCountã®ã±ãŒã¹ã§ã¯çå確èªã®æãå«ãã ã¢ã©ãŒãã«ãªãçºã 3åéããŒã¿ãå±ããªãã£ãå Žåã¯ã ã¡ããªã¯ã¹ããŒã¿ãå±ããŠããªããšããã¢ã©ãŒãã起祚ããããã«ãããã§ãã ãã®ãã signal lost after 3 minutes ã§ Open New âlost signalâ violation ã«ãã§ãã¯ãå
¥ããŸãã - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) HealtyHostCountã¯å®æçã«éèšãããŠéãããŠããç¶ç¶ããŒã¿ã§ãããã äžæ¹ã§ä»¥äžã®ããã«ããšããã€ãã³ããçºçãããšã ã ãã éããšãã£ãäžå®æãªããŒã¿ãååšããŸãã â»ç»é¢äŸã¯4XXãšã©ãŒã§ãã5XXãšã©ãŒã¯ãªããªãç»é¢ã·ã§ãããæ®ãããæã«çºçããŠãããªããã®ã§ããŠãããããã ãã®ãããªäžå®æããŒã¿ãã¢ã©ãŒããšããŠæ±ãå Žåã 以äžã§èª¬æããEvent Timerèšå®ã«ãã詳现ãªã³ã³ãããŒã«ãå¯èœã§ããããã ç¡å¹åããŠããããšãå人çãªããããã§ãã 3.Window Duration ãã€ã®ã¡ããªã¯ã¹ããŒã¿ãè©äŸ¡ããã®ããšããæ ã®æå®ã§ãã 1åéã®åèšãè©äŸ¡ããã®ãããããã¯5åéã®åèšãè©äŸ¡ããã®ãã è©äŸ¡ããããã®æéæ ã¯ããã§èšå®ããŸãã - äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) HealtyHostCountã®å ŽåãäžåºŠã§ã0ã ã£ãå Žåã äžå¥å
šãšã¿ãªããã¢ã©ãŒãçºå ±ããããã®ã§ å¯èœãªéãé »åºŠã®é«ãèšå®å€ã«ããŸãã ãã®ã¡ããªã¯ã¹ããŒã¿ã¯1åééèšãªã®ã§ã Window Durationã¯1åéãšããæ ã«ããŸãã - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) HTTPCode_Target_5XX_Countã¯5åéã®åèšå€ã1åéã®é »åºŠã§ç¢ºèªãããããã Window Durationã¯5åéã«èšå®ããŸãã 4.Slide by Interval Window Durationã§æå®ããæ ããã©ã®ãããã¹ã©ã€ãããŠè©äŸ¡ãããããšããæå®ã§ãã åŒç€Ÿã§ãå€ãã®äººã®çè§£ãæ«æã«å°ããèšå®å€ã§ããã é©åãªã¢ã©ãŒãããããããã«éèŠãªèšå®ã§ããããŸãã - äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) ãã®ã±ãŒã¹ã§ã¯äœ¿ããŸããã - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) Window Durationã5åéã«èšå®ããå Žåããã®Slide by Intervalã®èšå®ãããªããšã 5åéã«1åã®è©äŸ¡ããã§ããŸããã 5åéã®éèšã1åéã®é »åºŠã§è©äŸ¡ãããããã«ã¯ã 5åééèšã1å鿝ã«ã¹ã©ã€ããããŠè©äŸ¡ããå¿
èŠããããŸãã ãããå®çŸãããããã«ããã®ã±ãŒã¹ã§ã¯Slide by Intervalã®èšå®ã1åéã«èšå®ããŸãã åèã€ã¡ãŒãžïŒ https://docs.newrelic.com/docs/query-your-data/nrql-new-relic-query-language/nrql-query-tutorials/create-smoother-charts-sliding-windows ïŒ 5.Event flowã®Delay ãŸãã¯ãEvent Timerã®Timer Streaming Methodã«ãã£ãŠããã確å®ã«éèšããããã®èšå®ã§ãã ã¡ããªã¯ã¹ããŒã¿ãç¶ç¶çãªãã®ããäžå®æãªãã®ãã«ãã£ãŠã Event Flowã䜿ãããEvent Timerã䜿ããå€ãã£ãŠããŸãã Cadenceãšããèšå®ãããã®ã§ããã çŸåšã§ã¯éæšå¥šèšå®ãªã®ã§ãéžæè¢ããã¯é€å€ããŠããã§ãããã äŸA(ALBã®Healthy Host Countã0ã«ãªã£ããã¢ã©ãŒããã) HealtyHostCountã¯ç¶ç¶ããŒã¿ãªã®ã§ãEvent Flowã䜿ããŸãã çµè«ããäŒãããš2åéã®DelayãèšããŸãã ãã®èšå®ãå
¥ããããšã«ãããçŸåšã®æå»ã12:02ã ã£ãå Žåã11:59 ~ 12:00ã®ã¡ããªã¯ã¹ããŒã¿ãè©äŸ¡ããããã«ãªããŸãã Signal lossã®ç®æã§ã解説ããéãã ã¡ããªã¯ã¹ããŒã¿ã¯ãªã¢ã«ã¿ã€ã ã§å±ããªãå¯èœæ§ãããã ãã®èæ
®ããªããšé©åãªè©äŸ¡ãã§ããã éŸå€ãè¶
ããŠããã®ã«ã¢ã©ãŒãå€å®ããããªãâŠãšããç¶æ³ãèµ·ããããŸããã 2åéã®Delayãèšããããšã«ããã ã¡ããªã¯ã¹ããŒã¿ãå°çããŠããå¯èœæ§ãé«ããããšãã§ããŸãã ããã¯ç¢ºå®æ§ãšæ€ç¥ã¹ããŒãã®ãã¬ãŒããªãã«ãªãã®ã§ã é©åãªãã¥ãŒãã³ã°ãå¿
èŠãšãããŸãã ãŸãã2åéãèšããŠããã°ãæ€ç¥ã¹ããŒããšããŠåé¡ãšãªãã±ãŒã¹ãå°ãªãã§ãããã - äŸB (ALBã®HTTPCode_Target_5XX_Countã10以äžã«ãªã£ããã¢ã©ãŒããã) HTTPCode_Target_5XX_Countã¯äžå®æããŒã¿ãªã®ã§ã Event Timerã䜿ããŸãã çµè«ããäŒãããš5åéã®TimerãèšããŸãã ãã®èšå®ããããããšã«ããã 12:00ã«ååã®ã¡ããªã¯ã¹ããŒã¿ãå°çããå Žåã ãã®æç¹ãã5åéã®ã¿ã€ããŒãã»ãããããŸãã ãã®åŸã12:03ã«2åç®ã®ã¡ããªã¯ã¹ããŒã¿ãå°çããå Žåã ãã®æç¹ãã远å ã§5åéã®ã¿ã€ããŒãã»ããããã 12:08ã«12:00 ~ 12:05ã®ã¡ããªã¯ã¹ããŒã¿ãè©äŸ¡ãããŸãã ãã®Timerã¯ä»çµã¿äžã Window Durationãããå°ãªãæéãæå®ããããšãã¯éæšå¥šãªã®ã§ã ãã®ç¹ã¯æ³šæããŸãããã ãããã« ããã£ãšè©²åœé
ç®ã«é¢ããŠè§£èª¬ããŠã¿ãŸããããããã§ããããã äŸãªã©ãåºããŠããããããããã€ããã§ã¯ãããŸããã æ¹ããŠèŠè¿ããŠãã å¿
èŠãšãªãåæç¥èãèæ¯ãªã©ã®æ
å ±éã®å€ãæ
ã«è
°ãæ®ããŠã¿ãŠãããªããšçè§£ãé£ããåŽé¢ã¯ãããããããŸããã äœãããã¢ã©ãŒãèšå®ã§ã€ãŸã¥ããæã«ã§ãã ãããªããšæžããŠããã€ããããªãŒãšæãåºããŠããããã幞ãã§ãã ã¡ãã£ãšã ãå®£äŒ NRUG(New Relic User Group)ïŒéç§°ã¬ãã ãšãããŠãŒã¶ãŒã°ã«ãŒãããããŸãã åŒç€Ÿã§ãæ¿è°·ïŒ @mary_tuba ïŒãNRUGã®éå¶ã åãNRUG SREæ¯éšã®éå¶ãå€ããŠãããŸããŠãçŽè¿ã®äºå®ã¯ä»¥äžã«ãªããŸãã 12/14(æ°Ž) NRUG Vol.5 Day1 1åšå¹Žã ã!å
šå¡éå!! https://nrug.connpass.com/event/265357/ 12/15(æš) NRUG Vol.5 Day2 亀æµäŒÂ https://nrug.connpass.com/event/266747/ ?/? NRUG SREæ¯éš Vol.3 æ¥å¹Žæ¥é ãŸã§å¿
ãããããâŠ!! æ°ã«ãªãæ¹ã¯æ¯éãã§ãã¯ããŠã¿ãŠãã ããïŒ
ã¯ããã« â»ãã®èšäºã¯ mediba Advent Calendar 2022 ã®5æ¥ç®ã®èšäºã§ãã æ ªåŒäŒç€Ÿmediba ããã¯ãšã³ããšã³ãžãã¢ã® @hrktcy ã§ãã瀟äŒäºº2幎ç®ã«ãªããŸããã ã¿ãªããŸã®éçšãããµãŒãã¹ã«ã¯ç£èŠSaaSãå°å
¥ããŠããŸãããåŒç€Ÿã§ã¯ 1æ¥ç®ã®èšäº ã§ããäŒãããŠããéããè¿å¹ŽNew Relicã«ãããµãŒãã¹ç£èŠãäž»æµãšãªã£ãŠããŸããçŸåšç§ãåå ããŠããããã€ã³ããªã¯ãŒããµãŒãã¹ã«ããããã€ã³ãä»äžæ©æ§ã®éçºãããžã§ã¯ãã«ãå°å
¥ããéã³ãšãªããŸãããæ¬èšäºã§ã¯é¡ç®ã®éããNew Relic Alert Conditionèšå®ã«ãããããŒã ã§ã®åºæ¬æéãçå®ããã®ã§ãã®å
容ãå
±æããããšæããŸãã ã¢ããªã±ãŒã·ã§ã³åŽã®ã³ãŒãã®èŠçŽã ãŸãã¯Conditionã®èšå®ãããåã«ãã¢ããªã±ãŒã·ã§ã³åŽã®ã³ãŒãã®èŠçŽããè¡ãããšã«ããŸãããã³ãŒãã£ã³ã°ããŠããææããçµæ§æéã空ããŠããã®ã§ãèšæ¶ããæããŠããéšåãåããŠãããªããããé©åãªãšã©ãŒãã³ããªã³ã°ãã§ããŠããããã䜿çšããŠããã«ã¹ã¿ã ãã°ã®ãã°ã¬ãã«ãæ£ããããã®2ç¹ãéç¹çã«ãã§ãã¯ããŸããã ãã°ã¬ãã« å€ å
容 Info å®è¡ç¶æ
ãææ¡ããããã«åºåãããããã Warn èŽåœçã§ã¯ãªããæ³å®å€ã®æåããããšãã«åºåãã Error äºæããªããšã©ãŒã§ãµãŒãã¹åã³ã·ã¹ãã ã«åœ±é¿ããã調æ»åã³åŸ©æ§ãå¿
èŠãªæã«åºåãã ããªã·ãŒãåãã ããªã·ãŒãšã¯ã1ã€ä»¥äžã®ã³ã³ãã£ã·ã§ã³ã®ã°ã«ãŒããæããŸããä»åãããªã·ãŒã¯ä»¥äžã®2ã€ã«åããããšã«ããŸããã ãªã³ã³ãŒã«ããªã·ãŒ Slackéç¥ããªã·ãŒ ãªã³ã³ãŒã«ããªã·ãŒ æ€ç¥ãããå Žåãã€ã³ã·ãã³ããšãªãåŸãäºæ¡ã®ããè³æ¥å¯Ÿå¿ãå¿
èŠãªãã® ããªã³ã³ãŒã«ããªã·ãŒã«å²ãåœãŠãŸãããã°ã¬ãã«ã§èšããšErrorã¬ãã«ã®ãã®ãæããŸããå
·äœçã«ã¯ã ããããå€éèµ·åããŠãã AWSãµãŒãã¹ã®ã¯ã©ã€ã¢ã³ãèªèŸŒãã¢ã¯ã»ã¹ã«å€±æããŠãã å€éšãµãŒãã¹ãžã®ã¢ã¯ã»ã¹ãSFTPçµç±ã§ã®ããŠã³ããŒãã«å€±æããŠãã ãšãã£ããã®ã«ãªããŸãã ãã€ã³ã誀課éäºæ
ãé²ãããã«ããã®ãããªã€ã³ã·ãã³ãã«å¯ŸããŠã¯æ©æ¥ã«èª¿æ»ã»åŸ©æ§å¯Ÿå¿ããå¿
èŠãããã®ã§ãããŒã³ã段éã§ã¯NRQLã®æ¡ä»¶ãå³ããã«èšå®ããSlackéç¥+Twilioã§æ¥å端æ«ãžæ¶é»ããããã«èšå®ããŸããããããæ¡ä»¶ãå³ããã»ã©ãã¢ã©ãŒãã«ããç²åŒåé¡ã«ãåãåãå¿
èŠããããã€ã³ã·ãã³ã察å¿ããã»ã¹ã§ã±ã¢ã¬ã¹ãã¹ãã³ãã¥ãã±ãŒã·ã§ã³ãã¹ã«ç¹ããããããªãã®ã§ãæ¶é»å¯Ÿè±¡è
ã¯ã©ã³ãã (äžåšæã¯å¥ã®å¯Ÿè±¡è
ã«æ¶é»)ã«ããŠãNRQLæ¡ä»¶ã«ã€ããŠã¯ä¿å®éçšãå®å®ããŠãããå°ããã€ç·©åããŠãããããšèããŠããŸãã Slackéç¥ããªã·ãŒ æ€ç¥ãããå Žåãæ³å®å€ã®ãšã©ãŒã§ãµãŒãã¹åã³ã·ã¹ãã ã«åœ±é¿ããããã調æ»åã³åŸ©æ§ãè³æ¥ã§ã¯ãªããã® ãSlackéç¥ããªã·ãŒã«å²ãåœãŠãŸãããã°ã¬ãã«ã§èšããšWarnã¬ãã«ã®ãã®ãæããŸããå
·äœçã«ã¯ã ãã€ã³ãä»äžã«å€±æããŠãã CPU/ã¡ã¢ãª/DB䜿çšçãäžå®æén%ãè¶
ããŠãã DBã³ãã¯ã·ã§ã³æ°ãäžå®æénä»¶ä»¥äž ãšãã£ããã®ã«ãªããŸãã ããã€ã³ãä»äžã«å€±æããŠãããã«ã€ããŠã¯ããªã«ããªãŒãèæ
®ããèšèšã«ãªã£ãŠãããããåºæ¬çã«ã¯æ¥œèгèŠããŠãè¯ãã®ã§ãããæç¶çã«å€±æããŠããéã¯èª¿æ»ãå¿
èŠã«ãªããŸãããŸããã€ã³ãã©ã®ããã©ãŒãã³ã¹ç£èŠã«ã€ããŠãã¯ãŒãã³ã°ããªã·ãŒã«å²ãåœãŠãŠãããæ€ç¥ããããã¿ã€ãã³ã°ã§é«è² è·ãšãªã£ãŠããèŠå ã®èª¿æ»ãå¿
èŠã«ãªããŸãããã¡ãã®ããªã·ãŒã«ã€ããŠã¯Slackéç¥ã®ã¿è¡ãããã«èšå®ããŸããã ã³ã³ãã£ã·ã§ã³ã®ç®¡çã«ã€ã㊠Terraformã«ããIaCåãè¡ããããªã·ãŒã«çŽã¥ãã³ã³ãã£ã·ã§ã³ãäžå
管çããŸããã terraform apply ã§çŽ æ©ãAlert Conditionãèšå®ã§ããããã«ãªããããå°æ¥é¡§å®¢ãå¢ããå Žåã®ã€ã³ãã©ç°å¢ã®å¢ç¯ã«å¯ŸããŠãå³å¯Ÿå¿ãå¯èœã«ãªããŸãã å®éã©ãã ã£ãã ããŒã³ããã1ã¶æã»ã©çµã¡ãŸããããè³æ¥å¯Ÿå¿ãå¿
èŠãªäºæ¡ã¯çŸç¶1ä»¶ãæ€ç¥ã«ãã£ãŠè¿
éãªåŸ©æ§äœæ¥ãè¡ãããšãã§ããŸããããŸããããŒã³ãåŸã«ã¯Alert Conditionã«å ããŠAPMã«ããHTTPãã©ã³ã¶ã¯ã·ã§ã³ãã颿°ã»ã¯ãšãªåäœã§ã®èšè£
ãå®è£
ããããšãã§ãããµãŒãã¹ã®ä¿¡é Œæ§ç¶æã®äœå¶ãæŽã£ãŠããŠãããšæããŸãã çµããã« ç¹ã«ãªãªãžããªãã£ã®ããæéã§ã¯ãªããããããŸããããç§ã¯Alert Conditionèšå®ãããŠããéã«ããããããšèãéããŠããŸã沌ã«ã¯ãŸãããšã床ã
ãããŸãããããŒã ã¡ã³ããŒéã®èªèãåãããããã«ãäžåºŠèšèªåããŠãããšå°ã£ãæã«ç«ã¡è¿ãããšãã§ããããšæããŸãããŸãä»åŸã®æ°èŠéçºã®éã«ã¯ãäºãç£èŠå¯Ÿè±¡ãAlert Conditionèšå®ãæèããªããã³ãŒãã£ã³ã°ã§ããããã«å¿ãããŠããããã§ãã å®£äŒ KDDIã°ã«ãŒãäŒæ¥å瀟ã®Developerãéããããšã³ãžãã¢ã楜ããããã€ãã³ããæäŸããã³ãã¥ããã£KDDI Group Developer Community(KGDC)ã®éå¶ã¹ã¿ãããšããŠæŽ»åããŠããŸããæ¥å¹ŽãåŒãç¶ãéå¬ããŠãããŸãã®ã§ããã² Connpass ããã¡ã³ããŒã«ãªã£ãŠããã ããæ¬¡åã®ã€ãã³ãã«åå ããŠããã ãããšå¬ããã§ãïŒ
ããã«ã¡ã¯ãããŒã¿ã¢ããªã¹ãã®å·Šæµ·ã§ãã ä»åã¯ãã±ãããã£ããã£ããŒã«CharlesãæŽ»çšããŠã¬ã¹ãã³ã¹ããããŒã® Content-Security-Policy ãã£ãŒã«ãã«GA4ã®ãã£ã¬ã¯ãã£ãã远å ããã話ã«ã€ããŠæžããŠãããŸãã 課é¡ãšèæ¯ Universal Analyticsã®ãµããŒãçµäºçºè¡šã«äŒŽããåŒç€Ÿã§ã察象ã®ãµãŒãã¹ãµã€ãã«ãŠGA4ã®å°å
¥ãé²ããŠããã®ã§ãããCSP(Contents Security Policy)é¢é£ã§ãšã©ãŒãçºçãGA4ãã°ã®çéã確èªã§ããŸããã§ããã Google Chromeã®ããããããŒããŒã«ã§èª¿æ»ãããšããµã€ãã®CSPã«GA4ã®ãªãªãžã³ã宣èšãããŠãããããªãœãŒã¹ããããã¯ãããŠããããããã°ãé£ãã§ããªãããšã倿ããŸããã å ããŠã察象ã®ãµãŒãã¹ãµã€ãã¯å€éšã®äŒç€ŸãéçšããŠãããç§èªèº«ã®ç°å¢ã§ãããã¯ããå¿
èŠããã£ããããCharlesãæŽ»çšããããšã«ããŸããã æ¹ç Google Chromeã®Consoleã§ãšã©ãŒãã°ã確èªãããšãæé£ãããšã«ãšã©ãŒã®è§£æ±ºæ¹æ³ãŸã§èšèŒãããŠããŸãã A site’s Content Security Policy is set either as via an HTTP header (recommended), or via a meta HTML tag. HTTP ããããŒãŸãã¯HTMLã®ã¡ã¿ã¿ã°ã«ä»¥äžã®éãã«GA4ã®ãã£ã¬ã¯ãã£ãã宣èšããã°è§£æ±ºã§ããããã§ãã script-src: https://.googletagmanager.com img-src: https://.google-analytics.com https://.googletagmanager.com connect-src: https://.google-analytics.com https://.analytics.google.com https://.googletagmanager.com ã§ã¯ãå®éã«Charlesã®Rewriteãšããæ©èœã䜿çšããŠã¬ã¹ãã³ã¹ããããŒã® Content-Security-Policy ãã£ãŒã«ãã«GA4ã®ãã£ã¬ã¯ãã£ãã远å ããããã¯ããŠã¿ãããšã«ããŸãã CSP(Contents Security Policy)ãšã¯ Charlesã§ãããã¯ããåã«CSPã«ã€ããŠè§£èª¬ããŸããCSPã«ã€ããŠMDNã«ã¯ä»¥äžã®ããã«èšèŒãããŠããŸãã HTTP ã® Content-Security-Policy ã¬ã¹ãã³ã¹ããããŒã¯ããŠã§ããµã€ã管çè
ããããããŒãžã«ãŠãŒã¶ãŒãšãŒãžã§ã³ããèªã¿èŸŒã¿ãèš±å¯ããããªãœãŒã¹ã管çã§ããããã«ããŸããããã€ãã®äŸå€ãé€ããŠã倧åã®ããªã·ãŒã«ã¯ãµãŒããŒãªãªãžã³ãšã¹ã¯ãªãããšã³ããã€ã³ãã®æå®ãå«ãã§ããŸããããã¯ã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°æ»æ (ã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°) ãé²ãã®ã«åœ¹ç«ã¡ãŸãã https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy ã¬ã¹ãã³ã¹ããããŒã® Content-Security-Policy ãã£ãŒã«ãã«ãŠãµã€ãã«å¿
èŠãªãªãœãŒã¹ã宣èšããããšã§ãªãœãŒã¹ã®ç®¡çãè¡ããŸããCSPã«å®£èšãããŠããªããªãœãŒã¹ã¯èªã¿èŸŒãŸããªããããæªæã®ãããªãœãŒã¹ã®èªã¿èŸŒã¿ãåé¿ãã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°æ»æïŒXSSæ»æïŒãé²ãããšã«ã€ãªããããã§ãã Charlesã§ãããã¯ãã Charlesã®Rewriteãšããæ©èœã䜿çšããã°HTTPãªã¯ãšã¹ã/ã¬ã¹ãã³ã¹ã®å
å®¹ãæžãæããããšãå¯èœã§ããæ©éãã¬ã¹ãã³ã¹ããããŒã® Content-Security-Policy ãã£ãŒã«ãã«GA4ã®ãã£ã¬ã¯ãã£ãã远å ããŠãããŸãã 1.Charlesãéžæããç¶æ
ã§ã¢ããªã±ãŒã·ã§ã³ã¡ãã¥ãŒ > Tools > Rewriteãéžæãã Charlesãèµ·åããŠã¢ããªã±ãŒã·ã§ã³ã¡ãã¥ãŒ > Tools > Rewriteã®é åºã§æ·»ä»ç»åã®RewriteãéžæããŸãã 2.Enable Rewriteã®ãã§ãã¯ããã¯ã¹ã«ãã§ãã¯ãå
¥ããRewrite Settingsã远å ãã Rewrite Settingsã§Enable Rewriteãæå¹ã«ããRewriteã®èšå®ãæ°èŠäœæããã®ã§AddãéžæããŸããèšå®ã®åå㯠modify csp ãšããŸããã æ¬¡ã«ãRewriteã®å¯Ÿè±¡ãšãªã該åœã®URIãæ·»ä»ç»åã®èµ€æ ç®æã®Addããèšå®ããŠãããŸãã URIãProtocolãHostãPortãPathãQueryã«åããŠèšèŒããããšã§ãLocationã®èšå®ã¯å®äºã§ãã æåŸã«ãRewrite Ruleã«ãŠã¬ã¹ãã³ã¹ããããŒã® Content-Security-Policy ãã£ãŒã«ãã®ä¿®æ£ãèšå®ããŠãããŸããèµ€æ ç®æã®AddããURIã®èšå®ã®éãšåãããã«Rewrite Ruleã®æ°èŠäœæãè¡ããŸãã èšå®é
ç®ã«ã€ããŠé çªã«è§£èª¬ããŸãã Type å®è¡ããRewriteã®ã¿ã€ããæå®ããŸããä»åã¯ã¬ã¹ãã³ã¹ããããŒãä¿®æ£ããã®ã§ Modify Header ãéžæããŸãããã Where Rewriteãé©çšããå ŽæãéžæããŸããã¬ã¹ãã³ã¹ããããŒãä¿®æ£ããã®ã§ Response ã«ãã§ãã¯ãå
¥ããŸãããã Match ä¿®æ£ããããããŒåãšãã®å€ãæå®ããŸããå€ã¯ç©ºçœã«ããã©ããªå€ã§ã眮æãããããã«ã Match whole value ã«ãã§ãã¯ãå
¥ããŸãã倧æåãšå°æåãåºå¥ãããå Žå㯠Case sensitive ã«ãæ£èŠè¡šçŸã䜿çšãããå Žå㯠Regex ã«ãã§ãã¯ãå
¥ããŸãã Replace ä¿®æ£åŸã® Content-Security-Policy ãã£ãŒã«ãã®å€ãèšå®ããŸããå€ã«GA4ã®ãã£ã¬ã¯ãã£ãã远å ããŸããå€ã¯ãã¹ãŠæžãæããã®ã§ã Replace All ã«ãã§ãã¯ãå
¥ããŸãã 以äžã§Rewriteã®èšå®ã¯å®äºã§ãã 3.該åœã®ãµã€ãã«ãŠGA4ãã°ãæ£ããé£ãã§ããã確èªãã æ·»ä»ç»åã®éããæå³ããéãã«GA4ãã°ã確èªããããšãã§ããŸããã ãããã« Charlesã®Rewriteã¯ãå®éã«ãµãŒããŒã®èšå®ã倿Žããããšãªãç§èªèº«ã®ç°å¢ã§ãããã¯ããããšãå¯èœã§ããããªã䟿å©ã§ããã ä»åã®ç§ã®ã±ãŒã¹ã®ããã«ãå€éšã®äŒç€Ÿã«ãµã€ãã®éçšãäŸé ŒããŠããå Žåã¯åå 調æ»ã«æéãšã³ã¹ããããããšæããŸãã®ã§Charlesã®å©çšããã²æ€èšããŠã¿ãŠã¯ãããã§ããããã ã©ãªããã®åèã«ãªãã°å¹žãã§ãã
ã¯ããã« ããã«ã¡ã¯ããšã³ãžãã¢ã®äžçïŒ @yn2011 ïŒã§ãã ä»å¹Žã®4 æããçŸåšã®ããŒã ã§ããã¯ãªãŒãã®åœ¹å²ãæ
ãããã«ãªããéçºããŒã ã®ããã©ãŒãã³ã¹ã«é¢å¿ãæã€ããã«ãªããŸãããéçºããŒã ã®ããã©ãŒãã³ã¹ãšããæŒ ç¶ãšããããŒããåã«ãèªåã¯äœãããã¹ããªã®ã ãããïŒãšæ©ã¿ãªããæ
å ±åéãããŠããã®ã§ããã texta.fm #5 Accelerate ã§ Four Keys ãšåŒã°ããéçºçµç¹ã®ããã©ãŒãã³ã¹ææšïŒãšæžç±ã Lean ãš DevOps ã®ç§åŠ ãïŒã«ã€ããŠç¥ãããããã¯è¯ãããããšæãéçºããŒã ã«å°å
¥ããŠã¿ãããšã«ããŸããã ä»åã¯éçºããŒã ã Four Keys éçšã®æåã®äžæ©ãšããŠãã©ã®ãããªæè¡ãå©çšããŠèšæž¬ãšå¯èŠåãå®çŸãããã玹ä»ãããŠé ããŸãã ãªãããã Four Keys ã¯æ¢ã«ãŠãŒã¶ã«å¯ŸããŠãããã¯ããå
¬éããç¶ç¶çãªãªãªãŒã¹ãè¡ã£ãŠããããŒã ãåæãšããŠãããšèªèããŠããŸããã ç§ã®ããŒã ã§ã¯æ°èŠéçºãè¡ã£ãŠããŠããŸã ãããã¯ããå
¬éããŠããŸããã ãšã¯ãããæ°èŠéçºã«ãããŠãéçºã®çç£æ§ãå¥å
šæ§ã«é¢å¿ãæã€ããšã¯éèŠã ãšèããŠããŸããéçºããŒã ã®ããã©ãŒãã³ã¹ãå®éã§èªããç¶æ³ãäœãããšã§ãè§£ãã¹ã課é¡ãæããã«ããããŒã ãè¡ã£ãæ¹åã®çµæãæ£ããèªèããããšãã§ããŸãã Four Keys ãããŒã«ãšããŠæããã°ãæ°èŠéçºãè¡ã£ãŠããããŒã ã«ãããŠãæçšãªã®ã§ã¯ãªãããšãã仮説ã®å
ã æ¬è³ªãèŠå€±ããªãçšåºŠã« Four Keys ã®å®çŸ©ãããŒã ã«åãããã«å€æŽããããšã§ãæ°èŠéçºã«ãããŠãéçºããŒã ã®ããã©ãŒãã³ã¹ãå®éåã§ããã¯ãããšèãå°å
¥ã®æ€èšãå§ããŸããã äœããå§ããã ãŸãã¯ãçŸåšã®ããŒã ã® Four Keys ãèšæž¬ãå¯èŠåããä»çµã¿ãå¿
èŠã§ããFour Keys ã®éçšã¯ç§ãããŒã ã«ãšã£ãŠåããŠã®è©Šã¿ãªã®ã§ãæåãã倧æãããªèšæž¬ãšå¯èŠåã®ä»çµã¿ïŒã·ã¹ãã ïŒãæ§ç¯ããã®ã§ã¯ãªããã§ããã ãå°ããå§ããããšèšç»ããŸããã ããã§ãFour Keys ã®ãã¡éçºãªãŒãã¿ã€ã ãšãããã€æ°ã® 2 ã€ã®ææšã«çµãããšã«ããŸããã倿Žé害çãšãµãŒãã¹åŸ©å
æéã¯ååŸãé£ããããšãšããããã¯ããå
¬éããŠããªãã®ã§ããããå®çŸ©ã§ããªããšããã®ãçç±ã§ããã·ã¹ãã ã®ã¢ãŒããã¯ãã£ã GitHub Actions ãš GitHub Pages ã䜿ã£ãç°¡æçãªæ§æããå§ããŠã¿ãããšèããéçºãéå§ããŸããã 察象ãšããææšã«ã€ããŠã¯ãæ°èŠéçºã§ããããšãèæ
®ããŠä»¥äžã®å®çŸ©ãšããŸããã éçºãªãŒãã¿ã€ã : ã³ãããããŠãã main ãã©ã³ãã«ããŒãžããããŸã§ ãããã€æ°: main ãã©ã³ãã«ããŒãžããåæ°ïŒmain ãã©ã³ãã«ããŒãžãããšéçºç°å¢åãã®ãã«ããšãããã€ãè¡ãããïŒ ã·ã¹ãã æ§ç¯ ä»åã¯ä»¥äžã®æ©èœãæã€ã·ã¹ãã ãæ§ç¯ããŸããã ã¹ã±ãžã¥ãŒã«å®è¡ã§ãã 察象ã®ãªããžããªããéçºãªãŒãã¿ã€ã ãšãããã€é »åºŠãåéãã åéããããŒã¿ãå
ã«ææšãããã·ã¥ããŒããšã㊠Web ã«å
¬éããïŒãã ã瀟å
ã¡ã³ããŒã®ã¿ã¢ã¯ã»ã¹å¯èœïŒ ããã·ã¥ããŒãã®æŽæ°ã Slack éç¥ãã 以äžã«ã·ã¹ãã æŠèŠå³ã瀺ããŸãã ããã§ã¯ãã·ã¹ãã æŠèŠå³ãå
ã«è©³çްã«ã€ããŠã玹ä»ããŸãã ãªããžã㪠ããŒã¿åé察象ã®ãªããžããªãšã¯å¥ã«ãDashboard çšãªããžããªãæ°ãã«äœæããŸãããDashboard çšãªããžããªã§ã¯ãGitHub Actions ãå©çšããŠä»¥äžãè¡ã£ãŠããŸãã ãªããžããªããã®ããŒã¿åé Dashboard äœæ GitHub Actions ã§ã¹ã±ãžã¥ãŒã«å®è¡ãã ææšã¯ 1é±éã®äžå€®å€ãå¹³åå€ã§ç®åºãããã®ã§ãããŒã¿ã®åéãš Dashboard ã®æŽæ°ã¯é±ã« 1 床ã ãå®è¡ããŸãã äŸãã°ãæ¯é±æææ¥ã®æ¥æ¬æé 9 æã«å®è¡ããå Žåã¯ä»¥äžã®ããã«èšè¿°ããŸããã¹ã±ãžã¥ãŒã«å®è¡ã«å ããŠãæåã§å®è¡ãããå Žåã®ããã« workflow_dispatch: ãå«ããŠãããšäŸ¿å©ã§ãã // actions.yaml on: schedule: - cron: '0 0 * * 1' workflow_dispatch: åéãã shibayu36/merged-pr-stat ãå©çšããŠãéçºãªãŒãã¿ã€ã ïŒã³ããããã main ãã©ã³ãããŒãžãŸã§ã®æ¥æ°ïŒãšãããã€é »åºŠïŒPR ã®ããŒãžæ°ïŒãååŸããŸããïŒmain ãã©ã³ãã«ããŒãžããéã«ãã«ããšãããã€ãå®è¡ããŠããã®ã§ãããã€æ°ã¯ PR æ°ãšåçãšèŠãªããŠããŸãïŒ åŸç¶ã®ããã·ã¥ããŒãçæã§å©çšãããããååŸããçµæã¯ JSON ãã¡ã€ã«ãšããŠåºåããŸãã ä»åã¯ãå°ããå§ããããšããã³ã³ã»ããã§éçºããŠããã®ã§ã 1 床ååŸããããŒã¿ãæ°žç¶åãããGitHub Actions ãå®è¡ãã床ã«å
šãŠã®ããŒã¿ãåååŸããããšã«ããŸãããåœç¶æéã®çµéãšå
±ã« GitHub API ã®ãªã¯ãšã¹ãæ°ã¯å¢ããŠããŸããŸããããŸã ãããžã§ã¯ãã®éå§ãã3ã¶æçšåºŠããçµéããŠããªãã®ã§ãã°ããã¯å€§ããªåé¡ã«ã¯ãªããªãã ãããšãã倿ã§ãïŒãšã¯ãããã®ãã¡äœãšããããïŒ ã¡ãªã¿ã«ãåºæºæ¥ãã 7 æ¥éæ¯ã®ããŒã¿ãç¹°ãè¿ãååŸããããã zx ã§ã¹ã¯ãªãããæžã㊠merged-pr-stat ãå®è¡ããŠããŸãã å®è£
ã€ã¡ãŒãž while (startDate.add(7, "day").isBefore(now)) { // ...çç¥ await $`GITHUB_TOKEN=${process.env.GITHUB_TOKEN} yarn merged-pr-stat --start=${isoStartDateTime} --end=${isoEndDateTime} --query="repo:mediba/repo-name"`.pipe($`tail -n +2`); } â»è£è¶³ã§ãããã³ãããæ¥æãã³ãã³ãåŒæ°ã«äžãã察象æéå€ã§ã PR ããŒãžã察象æéã«å«ãŸããŠããã°èšæž¬å¯Ÿè±¡ã«ãªããŸãã zx ã䜿ãããšã§ãJavaScript ããçŽæçã«åãããããã·ã§ã«ã¹ã¯ãªãããå®è¡ãããã®çµæãå©çšããããšãã§ããŸãããŸããESM ã«å¯Ÿå¿ããŠãããã top level await ã䜿ããç¹ã䟿å©ã§ããä»åã¯å©çšããŠããŸãããã Promise.all ã§ã³ãã³ãå®è¡ã䞊ååããããšã§åŠçé床ãäžããããšãã§ãããã§ãã å¯èŠåãã åºåãã JSON ãã¡ã€ã«ãå
ã«ã°ã©ããæã㊠Next.js ã§ SSG ããŸãã react-chartjs-2 ãå©çšããŠä»¥äžã®ãããªã°ã©ããäœæããŸããã åèçšã«å®è£
äŸãæ²èŒããŸãã PR æ°ã®ã°ã©ãã®å Žåã¯ã以äžã®ããã«ãªãã·ã§ã³ïŒè»žã©ãã«ïŒãšããŒã¿ã»ãããå®çŸ©ã // 軞ã®èšå® const prOptions = { ...options, scales: { x: { title: { text: "é±", display: true, }, }, y: { title: { text: "PRæ°", display: true, }, }, }, }; // x 軞ã®ç®çãã©ãã« const labels = json.map((d) => `${d.startDate} é±`); // ããŒã¿ã»ãã const prs = { labels, datasets: [ { label: "1æ¥ã«ããŒãžããã PR æ°ã®é±å¹³å", data: json.map((d) => d.count / 7), borderColor: "rgb(53, 162, 235)", backgroundColor: "rgba(53, 162, 235, 0.5)", }, ], }; Line ã³ã³ããŒãã³ãã«åãæž¡ãã° OK ã§ãã <Line options={prOptions} data={prs} /> GitHub Pages ã«ãããã€ãã peaceiris/actions-gh-pages ãå©çšããŠãçæããããã·ã¥ããŒãã GitHub Pages ã«ãããã€ããŸããGitHub Actions 㯠main ãã©ã³ãã§å®è¡ããSSG ã§çæãããã£ã¬ã¯ããªã gh-pages ãã©ã³ãã«ã³ãããããŸãã éç¥ãã æåŸã«ããã·ã¥ããŒãã®æŽæ°ã Slack ã«éç¥ããŸããä»åã¯äœ¿ãæ
£ããŠããã®ã§ rtCamp/action-slack-notify@v2 ãå©çšããŸããã ç¶ç¶çã«ããŒã ã¡ã³ããŒãžå
±æããããšã§ Four Keys ã«å¯Ÿããæèãé«ãŸã£ãŠããããã§ãã ãŸãšã GitHub Actions ãš GitHub Pages ãå©çšããŠã宿çã«éçºãªãŒãã¿ã€ã ãšãããã€é »åºŠãåéãå¯èŠåããä»çµã¿ãäœãããšãã§ããŸããã ä»å㯠Four Keys ã«å¯Ÿããåãçµã¿ã®æè¡é¢ãã玹ä»ããŸããããä»åŸã¯æ°èŠéçºããŒã ã§ Four Keys ãèšæž¬ã»å¯èŠåããä»çµã¿ãå°å
¥ããçµæãã©ã®ãããªã¡ãªããããã¡ãªããããã£ãã®ãçéçºããã»ã¹ãšã®é¢ããã«ã€ããŠãã玹ä»ã§ããã°ãšæããŸãã æåŸãŸã§ãèªã¿é ãããããšãããããŸããã
ã¯ããã« ããã«ã¡ã¯ãSRE Unitã®å浊( @kitta0108 )ã§ãã çæ§ã仿¥ãå
æ°ã«ãã©ã³ããåã£ãŠããŸããïŒ åã¯ä»ãŸã§ãè³æ»ã§Developãã©ã³ããåã£ãŠã¯ã ãã ãã 空ãèŠã€ããã»ã»ã»ãããªäººçãéã£ãŠããŸããã ãããªåã«ãæãã®å
ãå·®ã蟌ã¿ãŸããŠã ãšãŠãäžæã«éçšããŠãããªãšæãããŒã ããã éçšè«ãå
·äœçãªæ¹æ³ãèãããšãã§ããŸãããä»åã¯ãã®å
容ãã玹ä»ããããšæããŸãã ⻠瀟å
ã§ã¯çºæ¡è
ã§ããäžå°ãã( @primunu )ã®ãååããåãããŠãshimoji-flowããšåŒã°ããŠããããã§ãã 䟿å®äžãåœããã°ã§ããã®ããã«åŒã°ããŠããã ãããšæããŸãã åããGitã®éçšã«æ±ããããš ããããã©ã³ãæŠç¥ãããã©ããã©ã³ãæŠç¥ã ã·ã¹ãã éçšã®å®å®åãšãã芳ç¹ã§ããéçºã¢ãžãªãã£åäžãšãã芳ç¹ã§ãããã©ã³ãæŠç¥ã粟é¬ãããæ¥ã
èŠçŽãããããŠããããšã¯æè³å¯Ÿå¹æã®é«ããã®ã ãšå人çã«ã¯æã£ãŠããŸãã å
容ã®ã玹ä»ã«å
¥ãåã«ãåããGitãéçšããã«ããã£ãŠã èæ
®ããã¹ããã®ã¯äžäœã©ã®ãããªãã®ãããã®ããæžãåºããŠã¿ãŸããã åç°å¢ã®ç¶æ
ãã©ã®ã³ãŒãããŒã¹ã§é©çšãããŠããã®ãå¯èŠæ§ãé«ãç¶æ
ã§ããããš éçšãã¬ããžã®ç¿åŸéãå°ãªããŠãéçšãã§ããããš = ã·ã³ãã«ã§ããããš é«éäžã€ä¿¡é Œæ§ã®é«ãããªããªãŒãå®çŸã§ããããš åããŒãžã§ã³ãžã®åãæ»ããé«éäžã€å®¹æã§ããããš ãã©ã³ãæ§æ äžèšãèžãŸãããã©ã³ãã®æ§æãéçšãµã€ã¯ã«ã以äžã®ããã«ããŸããã éçšãµã€ã¯ã« ããªããªãŒã®å·¥å€«ç¹ shimoji-flowã§ã¯ãããªããªãŒã®é床ãšä¿¡é Œæ§ã®åäžãå®çŸããããã«ã STG/PRDç°å¢åãã®ããªããªãŒã«é¢ããŠã¯ããã«ããšãããã€ã®ããªã¬ãŒãåé¢ãããŠããŸãã ãã«ãã®è²¬åã¯Releaseãã©ã³ãã®GitHashãã€ã¡ãŒãžã¿ã°ãšããŠãã³ã³ããã¬ãžã¹ããªãžã®ããã·ã¥ãŸã§ãè¡ãããšãšãã Releaseãã©ã³ãã«æ©èœçŸ€ãåºæã£ãã¿ã€ãã³ã°ã§ãã«ãã®ã¯ãŒã¯ãããŒãå®è¡ããããã«ããŠããŸãã ãŸããåããã«ãããäœæãããã³ã³ããã€ã¡ãŒãžãSTG/PRDç°å¢ã§åç
§ããããã«ãããŠããŸãã ãã®ããã«äžã€ã®ã³ãŒãããŒã¹ã«ããè€æ°ã®ãã«ã & ãããã€ãå®è¡ãããããšã«ããã ç°å¢å·®ç°ãæå°éã«æããæ€èšŒãå®çŸã§ãã = ä¿¡é Œæ§ã®åäž ãã«ããäºåã«è¡ãããŠãã = PRDç°å¢ãžã®ããªããªãŒã®é«éå ãå®çŸã§ããŠãããšæããŸãã â» ãåè: The Teweleve-Factor App I. CodeBase https://12factor.net/codebase ãŸãšã ããŠãã¡ãããšåé ã«è¿°ã¹ãèŠä»¶ãæºããããŠãããæ¯ãè¿ã£ãŠã¿ãŸãããã åç°å¢ã®ç¶æ
ãã©ã®ã³ãŒãããŒã¹ã§é©çšãããŠããã®ãå¯èŠæ§ãé«ãç¶æ
ã§ããããš ->Releaseãã©ã³ãã«ããåç°å¢ãžã®ãããã€åŸãç°å¢åã®ãã©ã³ãã«ããŒãžããããšã«ãããã³ãŒãããŒã¹ã§é©çšç¶æ
ããããããã«ãªããŸããã éçšãã¬ããžã®ç¿åŸéãå°ãªããŠãéçšãã§ããããš = ã·ã³ãã«ã§ããããš ->éçºã®é²è¡ã«ãããŠã¯ãReleaseãã©ã³ããžã®ããŒãžã ããèããã°è¯ããšããç¹ã§ãšãŠãã·ã³ãã«ããšæã£ãŠããŸãããã«ãããããã€ã®ã¯ãŒã¯ãããŒãå¿
ãReleaseãã©ã³ãããå®è¡ããããšããç¹ãä»çµã¿çã«ã·ã³ãã«ã§ãããã é«éäžã€ä¿¡é Œæ§ã®é«ãããªããªãŒãå®çŸã§ããããš ->äžèšã«è¿°ã¹ãããªããªãŒã®ä»çµã¿ã«ããå®çŸã§ããŸããã åããŒãžã§ã³ãžã®åãæ»ããé«éäžã€å®¹æã§ããããš ->åç°å¢åã®ãã©ã³ãã«ãªãªãŒã¹åŸãããŒãžããéçšãåãå
¥ããŠããã®ã§ãããåãæ»ããå¿
èŠã«ãªã£ãå Žåããã®ãã©ã³ãã®ã©ã®ã³ããããŸã§æ»ãã°ããã®ããšããç¹ã«è°è«ã¯åæãããŸãã ç°å¢åã®ãã©ã³ããååšããã®ã§ãããšèŠã®å¯èŠæ§ãé«ãã®ãå人çã«âãªç¹ããªãšæããŸãã ãããã« shimoji-flowãããã§ããã§ããããã ããã2幎ééçšããŠããŠãããããæ¹åããããŠãããšã®ããšã ã£ãã®ã§ãå®æåºŠã®é«ããã®ã ãšå人çã«ã¯æããŸããã è¯ããã®ã¯äžã«åºããã°ãšæã£ãŠçãåãããŠããã ããæ¬¡ç¬¬ã§ããããã¿ãªããã«ãããã©ã³ãæŠç¥èŠçŽãã®ãã£ãããããã©ã¯ãã£ã¹ã®åãå
¥ããªã©ã§æŽ»çšããã ããã倧å€ã«å¬ããæããŸãïŒïŒ
ã¯ããã« ããã«ã¡ã¯ããšã³ãžãã¢ã®éåŽã§ããæè¿ã¯çŸå Žã§ãããã¯ãã®éçºãè¡ãã€ã€ã å
ŒåãšããŠã»ã³ã¿ãŒå
šäœã®èª²é¡è§£æ±ºã«ããããããã¯ãªãŒããšããããŒã«ãæã¡ãè€æ°ã®ãããã¯ãã«ãŸããããã¯ãããžãŒã»ã³ã¿ãŒã®èª²é¡ã æè¡çãªç¹ã軞ã«ããªãã解決ã«åããŠåãçµãã§ããŸãã â»åèèšäºïŒ [2020幎床ãšã³ãžãã¢çµç¹ã«ã€ã㊠| mediba Creator à Engineer Blog] æ¬èšäºã§ã¯ã21å¹ŽåºŠäžæã«æ€èšãåãçµã¿å§ãã ãã·ã¹ãã ã¬ã€ãã©ã€ã³ã®éçšã ã«ã€ã㊠ãã®å
容ãšèæ¯ããäŒããŠããŠãããŸãã ç¹ã«ä»åŸãšã³ãžãã¢ãšããŠåŒç€Ÿã«å
¥ç€Ÿãæ€èšé ããæ¹ã«åããŠã ã©ã®ããã«æè¡ãšçµç¹ã«ã€ããŠèããŠãããããäŒãåºæ¥ãã°ãšæããŸãã medibaã«ãããéæ©èœèŠä»¶/éçšèŠä»¶ ãã®ã¬ã€ãã©ã€ã³ã¯åŒç€Ÿã®éçºã«ãããŠã æ©èœèŠä»¶ä»¥å€ã®ããããã éæ©èœèŠä»¶ãéçšèŠä»¶ ã«ã€ããŠã®ãã®ã«ãªããŸãã ãããã¯ãã®ãµãŒãã¹ã°ã¬ãŒããåæµã®éãã«ãã£ãŠå·®ç°ã¯ãããŸããã æŠããã®ãããã¯ãã ãã§ãã®éæ©èœèŠä»¶ãéçšèŠä»¶ã®ãã¹ãŠãå®çŸ©ãããããªããšã¯ãªãã medibaãšããŠããããã¯KDDIã°ã«ãŒãäŒæ¥ãšããŠ æšæºåãããéæ©èœèŠä»¶/éçšèŠä»¶ãããŒã¹ã«æ€èšããããšãã»ãšãã©ã§ãã ãããéæ©èœèŠä»¶/éçšèŠä»¶ã®å
容ã§ããã æ§èœãã»ãã¥ãªãã£ã«é¢ããã¢ããªã±ãŒã·ã§ã³ãã€ã³ãã©ã察象ã«ãããã®ã ã·ã¹ãã å
šäœã®å¯çšæ§ã察象ã«ãããã®ã ã·ã¹ãã ã®éçšã«ããã管çããªãªãŒã¹ãªã©ã察象ã«ãããã®ã ç£èŠãé害ã«é¢ãããã®ããªã©ãªã©å€å²ã«ããããŸãã ãŸãããããã®å®æœç®¡çã¯äžå
åãããŠããããã§ã¯ãªãããã ããé
ç®ã¯å
·äœçãªèŠä»¶ããèšå®æ¹æ³ã»å®çŸæ¹æ³ãŸã§èšèŒãããŠããã ãŸãããé
ç®ã¯èŠæ±äºé
ã®ã¿ãããªãå®çŸæ¹æ³ã¯åå¥ã«æ€èšãå¿
èŠãªãã®ãªã©ãããŸãã ãŸãåœç¶ãããã¯ãæ¯ã®æ©èœçãªèŠä»¶ãšããããã®éæ©èœèŠä»¶/éçšèŠä»¶ã®æŽåæ§ãåããªããŠã¯ãªããã ç·åçãªçè§£ãå¿
èŠãšãªã£ãŠããŸãã ãããã£ãé¢ãããéæ©èœèŠä»¶/éçšèŠä»¶ã®ææ¡ãããã®å®çŸæ¹åŒã®æ€èšãç¶ç¶çãªéçšãŸã§ ã©ãããŠãã¹ãã«ãçµéšãé«ããšã³ãžãã¢ã«éäžããã¡ã§å±äººåããããšã課é¡ãšãªã£ãŠããŸãã ãã®èª²é¡ã解決ããããã«ã ãã·ã¹ãã ã¬ã€ãã©ã€ã³ã ãåæŽåãããã®éçšãå§ããŸããã â»æ£ç¢ºã«èšããšããã·ã¹ãã ã¬ã€ãã©ã€ã³ãã®äœæã¯æ°å¹Žåã«äœæãããŠããŸããããçŸç¶ã®èª²é¡/éçšã«é©ããªããªã£ãŠããããåæŽåãè¡ã£ããšãã圢ãšãªããŸãã ã·ã¹ãã ã¬ã€ãã©ã€ã³ãšã¯ ã·ã¹ãã ã¬ã€ãã©ã€ã³ã¯ã Githubäžã§ç®¡çãããŠããããåæããšãã¢ããªã±ãŒã·ã§ã³ããã€ã³ãã©ããã»ãã¥ãªãã£ããã·ã¹ãã éçšãããªãªãŒã¹ããªã©ãšèšã£ããããªããã€ãã®æ¥åå¥ã®ããŒãžã«åãããŠããŸãã ãåæãã«ã¯ãã¬ã€ãã©ã€ã³ã®ç®çãäœ¿ãæ¹ãä¿®æ£æ¹æ³ãªã©ãèšèŒãããŠããŸãã æ¥åå¥ã®ããŒãžã®å
容ã¯ãäžè¿°ããéæ©èœèŠä»¶/éçšèŠä»¶ãå
ã«å
·äœçãªå®çŸæ¹æ³ãèšèŒããŠããŸãã äžäŸãšããŠããã¢ããªã±ãŒã·ã§ã³ãã®æ¥åå¥ã¬ã€ãã©ã€ã³ã«ãããŠã¯ã 管çã·ã¹ãã ã®ãã°ã¯ãã©ã®ãããªå
容ãåºåãããã»ã©ããããã®ä¿ææéã«ããã ãšãã£ãããšãå
·äœçã«èšèŒãããŠããŸãã ãã®ã¬ã€ãã©ã€ã³ãæ°èŠã¡ã³ããŒã®åç»æããããã¯ããŒã ã®çµææãªã©ã«èªã¿åããçè§£ãæ·±ããŠè²°ãã å®éã®ã·ã¹ãã ã®èšèšãå®è£
æã«ã©ã®ãããªå
容ã«ããã°è¯ããã®æå©ãã«ããŠããããããšèããŠããŸãã ãŸããã¬ã€ãã©ã€ã³ã®å
容ã®å€æŽã«é¢ããŠã§ããã ãã®ãããªæç« ã¯æšªæçãªéæ©èœèŠä»¶/éçšèŠä»¶ã®å€æŽãã¢ãŒããã¯ãã£ã®çºå±ãªã©ã«ãã ææ°ã«ä¿ã€å¿
èŠããããŸãã 倿Žããã®ãç¹å®ã®ãšã³ãžãã¢ã«åããªãããã«ããŸãçµç¹å
šäœã§å€æŽå
容ãè°è«ããŠããããã« ãšã³ãžãã¢ãªã誰ã§ãä¿®æ£ã®PullRequestãéãããããªãããŒã«ããŠããŸãã æåŸã« ä»åã¯ããã·ã¹ãã ã¬ã€ãã©ã€ã³ãã®éçšã«ã€ããŠãäŒããããŠé ããŸããã ãŸã éçšãå§ããã°ããã§ç®ã«èŠãã广ã¯ãããŸãããã çµç¹å
šäœã§ç¶ç¶çã«å
容ãçè§£ãä¿®æ£ããŠæŽ»çšããŠããããšã§ 暪æçã«ãããã¯ãã®å質åäžã«å¯äžããŠè¡ããšèããŠããŸãã ããžã§ã³ïŒãè¯ããã®ããå±ãç¶ãã ãŸãããã®åãçµã¿ã¯ãã¡ãšã³ãžãã¢ã®ã¹ãã«ã®åäžã«ãå¯äžãããšèããŠããŸãã ç§ãã¡ã®ããžã§ã³ã«ããè¯ããã®ããå±ãç¶ãããããããŸããã èªèº«ã®æé·ã«ãç¹ããŠã»ãããšã®æ³ãããããŸãã ãã·ã¹ãã ã¬ã€ãã©ã€ã³ããéããŠããè¯ããã®ããå±ãããããšã³ãžãã¢ã®æ¹ã®å¿åãmedibaã§ã¯ãåŸ
ã¡ããŠãããŸãã
ããã«ã¡ã¯ãmedibaã®ãšã³ãžãã¢ã«ã«ãã¹ã§ãïŒ æãæå·(crypto)ã«åŒ·ãé¢å¿ããã£ãã«ãããããããæå·é貚ã«ã¯ããŸãèå³ãæãŠãŸãããBitcoinã¯å§ãŸã£ãããã«å°ãæ¡æããŠããŸãããã倧ããéã¯çšŒãããŠã©ã¬ããã®ãã°ã€ã³æ¹æ³ãèŠããŠããŸããã å°ãçæŽ»åŽé¢ã®å
šãŠãèšè£
åãããçµæžã«ç§»è¡ããããšã«å¯ŸããçŸä»£ã®è奮ã«ã¯å
±æã§ããŸããã å³å¯ã«èšãã°ãæè¡çãªã¬ãã«ã ãšãç§ã¯ãŸã ä¿¡è
ã«ãªããŠããŸããã ããã§ãçŸåšweb3ã«ã€ããŠæ³šç®ãã¹ãç¹ããµãŸããäžã§ãããã€ãã®ç¹ã培åºçã«å匷ããŠãèŠéããŠããããšãããã確èªããããšã«ããŸããã Web 1.0ãš2.0ã«ã€ããŠã®æèŠ web3ã¯ããææ§ãªçšèªã§ãããweb3ã®éå¿ãå³å¯ã«è©äŸ¡ããããšã¯å°é£ã§ãããäžè¬çãªçè«ã§ã¯ã以äžã«ãªããŸãã web1:忣å web2:ãã¹ãŠããã©ãããã©ãŒã ã«éäžå web3:ãã¹ãŠãåã³åæ£å web3ã¯web2ã®è±ãããæäŸãã€ã€ã忣åãããŠããŸãã ãŸãã¯ãéäžåãã©ãããã©ãŒã ãäœæ
ç»å Žããçç±ãããçšåºŠæç¢ºã«ããã»ããããã§ããããç§ã®èãã§ã¯ã説æã¯éåžžã«ç°¡åã§ã! 誰ãèªåã®ãµãŒããŒã管çããããªãããæ±ºããŠããŸãã web1ã®åæã¯ããããäžã®å
šãŠã®äººãã³ã³ãã³ãã®çºè¡è
ã§ãããšåæã«æ¶è²»è
ã§ãããã€ã³ãã©ã¹ãã©ã¯ãã£ã®çºè¡è
ãšæ¶è²»è
ã§ããããšããããšã§ããã çããå人ãµãŒããŒã®äžã«å人ãŠã§ãããŒãžããã¹ãããå人ã®ã¡ã¢ãã®ããã®å人ã®ã¡ãŒã«ãµãŒããŒãçšæããå人ã®ã¹ããŒã¿ã¹ã¡ãã»ãŒãžçšã®å人ã®ãã£ã³ã¬ãŒãµãŒããŒãããããã«ããŸãã ãããã匷調ããŠãããããããšã¯ãªãã ãããšæããŸãããäžè¬ãŠãŒã¶ãŒããããæãã§ããããšã§ã¯ãªãã§ããããäžè¬ãŠãŒã¶ãŒã¯èªåã®ãµãŒããŒã管çããããªãããããã¯ãªã¿ã¯ã§ãããããªãããšã§ãããœãããŠã§ã¢ãéçºããŠããçµç¹ã§ãããçŸæç¹ã§ã¯ãµãŒããŒã管çããããªãã§ããç§ãã¡ããã®äžçã«ã€ããŠåŠãã ããšã1ã€æãããšããããããã¯äººéããµãŒããŒã管çããããªããšããããšã§ãã ã ããã代ããã«ãã®ãµãŒãã¹ãæäŸããŠãããäŒç€Ÿã¯æåããŸããããããŠããããã®ãããã¯ãŒã¯ã®äžã®å¯èœã§ããããšãæ¡åŒµããŠæ°ããæ©èœãã€ãã¬ãŒã·ã§ã³(â»ïŒ)ããäŒç€Ÿã¯ããã«æåããŸããã ãããã³ã«ã¯ãã©ãããã©ãŒã ãããã¯ããã«ãã£ãããšç§»åããŸã 30幎以äžçµã£ãŠããé»åã¡ãŒã«ã¯ãŸã æå·åãããŠããŸãããäžæ¹ãWhatsAppã¯1å¹Žã§æå·åãããŠããªãç¶æ
ããå®å
šãªe2eeã«ç§»è¡ããŸããã æªã ã«IRCãä»ããŠãããªã確å®ã«å
±æããããšãæšæºåããããšããŠããŸãããäžæ¹ãSlackã§ã¯ããŠãŒã¶ãŒã®è¡šæ
ã«åºã¥ããŠã«ã¹ã¿ã ã®ãªã¢ã¯ã·ã§ã³çµµæåãäœæã§ããŸãã ããã¯è³é調éã®åé¡ã§ã¯ãªããäœããå®å
šã«åæ£åãããŠãããšã倿Žãéåžžã«é£ãããªããæã®æµãã®äžã§åãæ®ããããŸãŸã«ãªãããšããããããŸããããã¯ãã¯ãããžãŒã®åé¡ã§ããããšã³ã·ã¹ãã ã®åããéåžžã«éããŠåžžã«äžŠèµ°ããŠããªããã°çœ®ããŠããããŸããèšå€§ãªæ°ã®äººã
ã®ã°ã«ãŒããç·šæããŠæ©ãç§»åã§ããããã«ããæ¹æ³ãèŠã€ããããšãéåžžã«éèŠã§ãããããã¢ãžã£ã€ã«ã®ãããªæ¹æ³è«ã®å®çŸ©ãšæ¹åã«çŠç¹ãåœãŠãäžŠè¡æ¥çå
šäœãååšããã®ã§ãããã ãã¯ãããžãŒèªäœãåããããåæ»ãå©é·ãããšãªããšå€§åé¡ã§ããæåã®ç¢ºå®ãªç§èš£ã¯ãæéã«è¿œãããŠãã90幎代ã®ãããã³ã«ãæ¡çšãããããéäžåããŠãè¿
éã«å埩ããããšã ãšèããããŸãã ããããweb3ã®æå³ã¯éããšããã«ããã®ã§ããã®ããšã確èªããŠã¿ãŸããããæè¡ã®æããã€ããã§å°æ¥ãã©ããªãããããããçè§£ããããã«ããã€ãã®dAppãå©çšããŠNFTãäœæããããšã«ããŸãããïŒä»åŸèªåã§äœæãããã¿ãããšæããŸãã…ïŒ åæ£åã¢ããªã±ãŒã·ã§ã³(dApp)ã䜿ã£ãŠã¿ãŸãã web3ãæãåãããã« AutonomousArt ãšããdAppã䜿ã£ãŠã¿ãŸãããããã«ãããNFTã«èŠèŠçãªè²¢ç®ããããšã§ã誰ã§ãNFTã®ããŒã¯ã³ãçºè¡ã§ããŸããèŠèŠçãªè²¢ç®ãããããã®ã³ã¹ãã¯æéã®çµéãšãšãã«å¢å ããè²¢ç®è
ããã³ãã®ããã«æ¯æãè³éã¯ä»¥åã®ãã¹ãŠã®è²¢ç®è
ã«åé
ãããŸãïŒãã®è²¡åæ§é ã¯ãã©ãããåã«äŒŒããã®ã«ãªããŸãïŒã ãããŠãåè³ç£ã远跡ããéèããªããã£ãã®ããã«ãåè³ç£ã远跡ããNFTããªããã£ããäœæãçºèŠã亀æãããŠããã FirstDerivative ãšããdAppã䜿ã£ãŠã¿ãŸããã ã©ã¡ããdAppã®ä»çµã¿ãæããããŠãããŸãããæ£çŽã«ãããšãã¢ããªèªäœã«ã€ããŠç¹ã«ã忣ããããŠãããã®ã¯ãããŸããã§ãããã¢ããªã¯éåžžã®Reactã®ãŠã§ããµã€ã… ãã®ã忣æ§ããšã¯ãã¹ããŒããšãã®ã¹ããŒããæŽæ°ããããã®ããžãã¯/æš©éãååšããå Žæã«ãªããŸãããã®å Žæã¯ãéäžåãããŒã¿ããŒã¹ã§ã¯ãªãããããã¯ãã§ãŒã³ã®äžã§ãã ç§ããã€ããããããšæã£ãŠããã®ã¯ãã¯ã©ã€ã¢ã³ã/ãµãŒããŒã®ã€ã³ã¿ãŒãã§ã€ã¹ãžã®æ³šæã®æ¬ åŠã§ãã誰ãããããã¯ãã§ãŒã³ã«ã€ããŠè©±ããšãã«ã¯ãä¿¡é Œã®åæ£ãæå°è
ã®ãªãç·æããããŠä»çµã¿ãã©ã®ããã«åããŠãããã«ã€ããŠè©±ããŸãããå€ãã®å Žåæçµçã«ã¯ã©ã€ã¢ã³ããã§ããªãããšã¯äœã§ããããããããã«ãªã£ãŠããããã«æããŸãã ã©ããªãããã¯ãŒã¯å³ã«ãèŒã£ãŠãããã®ã¯ãµãŒããŒã°ããã§ãä¿¡é Œã¢ãã«ããµãŒããŒéã®ãã®ã§ããããã¹ãŠã¯ãµãŒããŒã«é¢ãããã®ã§ãããããã¯ãã§ãŒã³ã¯ãã¢ã®ãããã¯ãŒã¯ãšããŠèšèšãããŠããŸãããã¢ãã€ã«ããã€ã¹ãŸãã¯ãã©ãŠã¶ããã¢ã«ãªããããã«ã¯èšèšãããŠããŸããã ããšãã°ãã¢ãã€ã«ã§ãPCã§ããAutonomousArtãFirstDerivativeã®ãããªdAppã¯ãã¹ããŒãã®å€æŽãŸãã¯ã¬ã³ããªã³ã°ããããäœããã®æ¹æ³ã§ãããã¯ãã§ãŒã³ãšããåãããå¿
èŠããããŸãããã ãããããã¯ãã§ãŒã³ã¯ã¢ãã€ã«ããã€ã¹ïŒãããã¯ïŒ°ïŒ£ãã©ãŠã¶ãŒïŒäžã§åäœã§ããªããããã¯ã©ã€ã¢ã³ãåŽãããããè¡ãããšã¯å®éã«ã¯äžå¯èœã§ãããããããã£ãŠãå¯äžã®ä»£æ¿ææ®µã¯ã©ããã®ãµãŒããŒäžã§ãªã¢ãŒãã§å®è¡ãããŠããããŒããä»ããŠãããã¯ãã§ãŒã³ãšå¯Ÿè©±ããããšã§ãã ãã£ã±ããµãŒããŒã ïŒã§ãããã§ã«æžããããã«ã人ã¯ãµãŒããŒã管çããããããŸãããå¶ç¶ã«ãããµãŒãã¹ãšããŠetheriumããŒããžã®APIã¢ã¯ã»ã¹ã販売ããäŒæ¥ãåºçŸããåæãæ¡åŒµAPIãããã³å±¥æŽãã©ã³ã¶ã¯ã·ã§ã³ãžã®ã¢ã¯ã»ã¹ãæäŸããŠããŸãããªããèããããšãããŸããã…çŸæç¹ã§ãã»ãšãã©ãã¹ãŠã®dAppã¯ããããã¯ãã§ãŒã³ãšå¯Ÿè©±ããããã«2ã€ã®äŒç€Ÿã䜿ã£ãŠããŸããInfuraãŸãã¯Alchemyãå®éãMetaMaskã®ãããªãŠã©ã¬ãããdAppã«æ¥ç¶ããdAppããŠã©ã¬ãããä»ããŠãããã¯ãã§ãŒã³ãšå¯Ÿè©±ããå Žåã§ããMetaMaskã¯InfuraãåŒã³åºããŠããã ãã§ãã ãããã®ã¯ã©ã€ã¢ã³ãAPIã¯ããããã¯ãã§ãŒã³ã®ç¶æ
ãå¿çã®ä¿¡é Œæ§ãæ¿èªããããšããŠããŸãããçµæã¯çœ²åãããããŠããŸãããAutonomousArtã®ãããªã¢ããªã¯ãããã®ã¹ããŒãã³ã³ãã©ã¯ãã§ã®ãã®ãã¥ãŒæ©èœã®åºåã¯äœã§ããããšèšããŠãAlchemyãŸãã¯Infuraã¯ããããã¯åºåã ãããšããJSON BLOBã§å¿çããã¢ããªããããã¬ã³ããªã³ã°ããŸãã ããã¯é©ãã§ãããä¿¡çšäžèŠ(â»2)ã®åæ£åã³ã³ã»ã³ãµã¹ã¡ã«ããºã (â»3)ã®æ§ç¯ã«ã¯å€å€§ãªåŽåããšãã«ã®ãŒãæéãè²»ããããŠããã®ã«ãããã«ã¢ã¯ã»ã¹ãããã»ãšãã©ã®ã¯ã©ã€ã¢ã³ãã¯ãæ€èšŒãªãã«ããã®2ã€ã®ãµãŒãã¹ããã®åºåãåã«ä¿¡é ŒããŠããŸãããŸãããã©ã€ãã·ãŒã®é¢ãããæåã§ã¯ãªãã§ãããããã¹ãŠã®writeãã©ãã£ãã¯ã¯ããã¡ãããããã¯ãã§ãŒã³äžã§ãã§ã«å
¬éãããŠããŸããããã®2ã€ã®ãµãŒãã¹ã¯ã»ãŒãã¹ãŠã®dAppã®ãŠãŒã¶ãŒããã®èªã¿åãèŠæ±ãå¯èŠåããããšãå¯èœãšãªã£ãŠããŸãã NFTãäœã ãããããããå°ãäžè¬çãªïŒ®ïŒŠïŒŽãäœæããŠã¿ãããšæããŸãããã»ãšãã©ã®äººã¯ãNFTã«ã€ããŠèãããšãã«ç»åãããžã¿ã«ã¢ãŒãã«ã€ããŠèããŸãããæ®æ®µã¯NFTããã®ããŒã¿ããã§ãŒã³äžã«ä¿åããŠããããã§ã¯ãããŸãããã»ãšãã©ã®ç»åã®NFTã®å Žåãããã¯éåžžã«è²»çšã®ããããã®ã§ããç»åã®ããŒã¿ããã§ãŒã³ã«ä¿åãã代ããã«ãããŒã¿ãæãURLã«ãªã£ãŠããŸãããã®æšæºã«ã€ããŠç§ãé©ããã®ã¯ãURLã«ããããŒã¿ã«ããã·ã¥ã³ãããã¡ã³ãããªãããšã§ããæ°åãã«ãæ°çŸãã«ããŸãã¯æ°çŸäžãã«ã§è²©å£²ãããŠãã人æ°ã®ããåžå Žã®NFTãèŠããšããã®URLã¯ãApacheãå®è¡ããŠããVPSãæããŠããããšãããããããã§ãããã®ãã·ã³ã«ã¢ã¯ã»ã¹ã§ãã人ãå°æ¥ãã®ãã¡ã€ã³åã賌å
¥ãã人ããŸãã¯ãã®ãã·ã³ã䟵害ãã人ã¯ãNFTã®ç»åãã¿ã€ãã«ã説æãªã©ããã€ã§ã奜ããªããã«å€æŽã§ããŸãïŒãã®ããŒã¯ã³ããææãããŠããªãã«ããããããïŒãNFT仿§ã«ã¯ãç»åããããã§ããã¹ãããããæ£ããããã©ãã確èªãããŠããããã®ã¯äœããããŸããã ã€ã³ã¿ãŒããããåçŸãã web1ãweb2ã«ãªã£ãçç±ãèãããšãweb3ã®å¥åŠãªãšããã¯ãethereumã®ãããªæè¡ãweb1ã§æ¢ã«æããã«ãªã£ãŠããã¯ãå€ãçœ ã§æ§ç¯ãããŠããããšã§ãããããã®æè¡ã䜿çšå¯èœã«ããããã«ããã©ãããã©ãŒã ãäžå¿ã«çµ±åãããŠããŸãããŸãåãããšãèµ·ãã£ãŠããŸããããªãã®ä»£ããã«ãµãŒããŒãéå¶ããåºçŸããæ°ããæ©èœãã€ãã¬ãŒã·ã§ã³ãããµãŒãã¹ãããã¯InfuraãOpenSeaãCoinbaseãEtherscanããªã©ã§ãã åæ§ã«ãweb3ãããã³ã«ã®é²åã¯é
ãã§ãã äŸãã°ã FirstãDerivativeã¯åè³ç£ã®äŸ¡å€ã®ããŒã»ã³ããŒãžãšããŠãã³ãã®äŸ¡æ Œãèšå®ããããšãã§ããããã©ããã®ããŒã¿ã¯ãã§ãŒã³äžã«ãããŸãããOpenSeaãæäŸããAPIå
ã«ãããŸããå€ãã®äººãã¯ãªãšã€ã¿ãŒã«å©çãããããæ¹æ³ã§NFTã®ç¹èš±æš©äœ¿çšæã«æåŸ
ããŠããŸãããäœ¿çšæã¯ERC-721ã§æå®ãããŠãããã倿Žããã«ã¯é
ãããŸãããã®ãããOpenSeaã«ã¯ãweb2ã¹ããŒã¹ã«ãã®äœ¿çšæãæ§æããç¬èªã®æ¹æ³ããããŸããéäžåãã©ãããã©ãŒã ã§ã®è¿
éãªå埩ã¯ããã§ã«åæ£ãããã³ã«ãäžåããå¶åŸ¡ããã©ãããã©ãŒã ã«çµ±åããŠããŸãããã®æ¹æ³ã ãšæå·é貚ãŠã©ã¬ããã§ã®NFTã®ãã¥ãŒãOpenSeaã®NFTã®ãã¥ãŒã«ãªã£ãŠãããšããŠãé©ãã¯ãªãã§ããããOpenSeaã¯ãæšæºã倿Žããããšãäžå¯èœ/å°é£ã§ãå¯èœãªç¯å²ãè¶
ããŠãã©ãããã©ãŒã ãå埩ããããšã«å¿ããããã眮ãæãå¯èœãªçŽç²ãªããã¥ãŒãã§ã¯ãªãããšã«é©ãããšã§ã¯ãããŸããã ããã¯ã¡ãŒã«ã®ç¶æ³ãšéåžžã«äŒŒãŠãããšæããŸããèªåã®ã¡ãŒã«ãµãŒããŒãéçšããããšã¯ã§ããŸããããã©ã€ãã·ãŒãæ€é²ãžã®æµæããŸãã¯å¶åŸ¡ã«é¢ããŠã¯ãç§ãéåä¿¡ãããã¹ãŠã®ã¡ãŒã«ã®è£ã«GMailããããããçµå±æå³ããããŸããã忣åãšã³ã·ã¹ãã ãå©äŸ¿æ§ã®ããã«ãã©ãããã©ãŒã ãäžå¿ã«éäžãããšãäž¡æ¹ã®äžçã®æªãéšåã ããæœåºãã圢ã«ãªã£ãŠããŸããŸããéäžç®¡çãããŠããŸãããæéå
ã«æ··ä¹±ããã»ã©ååã«åæ£ãããŠããŸããèªåã®NFTããŒã±ãããã¬ã€ã¹ãæ§ç¯ããããšã¯ã§ããŸãããOpenSeaããŠãŒã¶ãŒã䜿çšãããŠã©ã¬ããå
ã®ãã¹ãŠã®NFTïŒããã³ãšã³ã·ã¹ãã å
ã®ä»ã®ãã¹ãŠã®ã¢ããªïŒã®ãã¥ãŒã仲ä»ããããç¹å¥ãªå¶åŸ¡ã¯äœãæäŸã§ããŸããã åµé æ§ã¯ååã§ã¯ãªããããããŸãã web3ã詊ãã«å°ããã£ãŠã¿ãã ãã§ããããã®å°ããªè©Šãã®èŠç¹ããèŠãŠã¿ããšããªãããã»ã©å€ãã®äººãã¡ãweb3ãšã³ã·ã¹ãã ããšãŠããããã ãšæãã®ããç°¡åã«ããããŸããéäžåããããã©ãããã©ãŒã ããé¢ããŠãããè»éã«ãªã£ãŠããããšããã¯ãããžãŒãšã®é¢ä¿ãæ ¹æ¬çã«å€ãããšã¯æããŸãããããã©ã€ãã·ãŒã®ãšããããã§ã«ã€ã³ã¿ãŒãããã®æ°Žæºãäžåã£ãŠãããšæããŸãããç§ã®ãããªéçºè
ãããã§äœããæ§ç¯ããããšã«è奮ããŠããçç±ãããããŸããå°ãªããšãæ°ãããã®ã§ãããåæã®ã€ã³ã¿ãŒãããæä»£ãæãåºãããåµé æ§/æ¢çŽ¢åºæ¥ããããªã¹ããŒã¹ã«ãªã£ãŠããããã§ããç®èãªããšã«ããã®åµé æ§ã®äžéšã¯ãããããweb3ãéåžžã«äžæ Œå¥œã«ããå¶çŽããçããŠããŸããä»ç®ã«ããŠããåµé æ§ã𿢿±ãååããªçµæãããããããšãé¡ã£ãŠããŸãããéå»ã®ã€ã³ã¿ãŒããããšåãåž°çµãé²ãããã«ååãã©ããã¯ããããŸããã ãã¯ãããžãŒãšã®é¢ä¿ãæ¹åãããã®ãªããæå³çã«ãããªããã°ãªããªããšæãã®ã¯ïŒ ã€ã³ãã©ã¹ãã©ã¯ãã£ã忣ãããã«ä¿¡é Œã忣ã§ããã·ã¹ãã ãèšèšããããšã§ãçãèªåã®ãµãŒããŒã管çããªããšããåæãåãå
¥ããå¿
èŠããããŸãã ãœãããŠã§ã¢æ§ç¯ã®è² æ
ã軜æžããããåªããã¹ãã§ãã ããããæ£çŽãããšGameStopãšLoopRingãäœãããšããŠããããŒã±ãããã¬ã€ã¹ã«ã¯å°ãæåŸ
ããããŸãïŒïŒ ç§ããã¯ä»¥äžã§ããæåŸãŸã§èªãã§ããã ãããããšãããããŸããã åè â»1 https://it-trend.jp/development_tools/article/32-0022 â»2 https://komugi.jp/?p=859 â»3 https://support.okcoin.jp/hc/ja/articles/4403552067865
ããã«ã¡ã¯ãããŒã¿ã¢ããªã¹ãã®å·Šæµ·ã§ãã æè¿ã¢ãµã€ã³ããããããžã§ã¯ãã«ãŠã¢ããª/Webã®Google Analytics 4(以äžGA4)ã§ã®èšæž¬ãæ€èšããŠããŸããããç§èªèº«ã¢ããªãGA4ãç¥èŠããªãã£ããããSwiftUIã§ãã€ãã£ãã¢ããªãäœæããã°æ€èšŒãè¡ãããšã«ããŸããã â»ãªããApple Developer Programãå¥çŽããŠããªãããiOS Simulatorã䜿çšããŠããŸãã å®è¡ç°å¢ Xcodeã®VersionïŒ13.2.1 (13C100) iOS Simulatorã®ååïŒiPhone 13 iOSã®versionïŒiOS 15.2 æçµçã«ã§ããã㮠以äžã®éãããã¹ãã¢ããªãäœæãGA4ã®DebugViewã§screen_viewã€ãã³ããã«ã¹ã¿ã ã€ãã³ããæå³ããã¿ã€ãã³ã°ã§é£ãã§ãããæ€èšŒå¯èœã«ãªããŸããã äœæ¥æé 以äžã®äœæ¥æé ã®éãã«é²ããŠãããŸãã SwiftUIã§ãã€ãã£ãã¢ããªã®äœæãè¡ã ãã€ãã£ãã¢ããªãžFirebase SDKã远å ãã GA4ã®DebugViewã§ãã°ãæ€èšŒãã ããã§ã¯ããã€ãã£ãã¢ããªäœæã®æµããFirebase SDKã®è¿œå ãGA4ãçšãããã°æ€èšŒã«ã€ããŠèª¬æããŠãããŸãã 1.SwiftUIã§ãã€ãã£ãã¢ããªã®äœæãè¡ã ç»é¢é·ç§»ã®ã€ã¡ãŒãž ãŸãã¯ãXcodeã§Firebase SDK远å ã«å¿
èŠãªã¢ããªã®äœæãè¡ããŸãã ããã§ã¯ã3ã€ã®ç»é¢ãäœæããŸããç»é¢é·ç§»ã¯æ·»ä»ç»åã®ãããªã€ã¡ãŒãžã§ãã ContentView SubView MyWebView ContentViewã®äœæ ContentViewããäœæããŸããContentViewã§ã¯ãSubViewãMyWebViewããããã«é·ç§»ãããªã³ã¯ãäœæããButtonãç»é¢å³äžéšã«é
眮ããŸããå ããŠãã€ãã³ãéä¿¡åŠçã远å ããŸãã ç»é¢é·ç§»ã¯ä»¥äžã®éã NavigationLink ãçšããŸãã destination ã«ã¯é·ç§»å
ã®Viewåãã Text() ã«ã¯ãªã³ã¯ã«è¡šç€ºããæååãèšè¿°ããŸãã NavigationLink(destination: SubView()) { Text("Go SubView") } NavigationLink(destination: MySecondWebView(urlString: "https://test-c1632.web.app/")) { Text("Go WebView") } screen_viewã€ãã³ãã¯ã€ã³ã¹ã¿ã³ã¹ã¡ãœãã onAppear ã§ContentViewãæç»ãããã¿ã€ãã³ã°ã§éä¿¡ããŸãã ã€ãã³ããã©ã¡ãŒã¿ãŒãšããŠã screen_name ãš screen_class ãå®çŸ©ããŠãããŸãã åæ§ã®åŠçãSubViewãMyWebViewã§ãèšè¿°ããŠãããŸãã .onAppear() { Analytics.logEvent(AnalyticsEventScreenView, parameters: [AnalyticsParameterScreenName: "\(ContentView.self)", AnalyticsParameterScreenClass: "\(ContentView.self)"] ) } 次ã«ãç»é¢å³äžéšã®Buttonãã¿ããããéã«éä¿¡ããã«ã¹ã¿ã ã€ãã³ã button_tap ã远å ããŸããã€ãã³ããã©ã¡ãŒã¿ãšã㊠button_name ãå®çŸ©ããŸããä»åéä¿¡ããã€ãã³ãéä¿¡åŠçã®èšè¿°ã¯ä»¥äžã§ãã Button(action: { let button_name = "hoge" Analytics.logEvent("button_tap", parameters: ["button_name" : button_name as NSObject,] ) } SubViewã®äœæ ContentViewã®é·ç§»å
ã§ããSubViewã®äœæãè¡ããŸããããã§ã¯ãããŒã®é·ç§»å
ãèšå®ããŠãããŸããã MyWebViewã®äœæ ContentViewã®é·ç§»å
ã§ããMyWebViewç»é¢ã®äœæãè¡ããŸããMyWebViewç»é¢ã¯ç§ãäœæããWebãµã€ãã衚瀺ããŸãã Webãµã€ãã¯Firebase Hostingã§å
¬éããŠããŸãã ããã§ã¢ããªã®äœæã¯çµäºã§ãã以äžã®éããåé¡ãªããã«ãããããšãã§ããŸããã 2.ã¢ããªãžFirebase SDKã远å ãã ã¢ããªã«æ¥ç¶ããFirebase ãããžã§ã¯ããæ°èŠäœæãã äœæããã¢ããªã«Firebase SDKã远å ããŸãããŸãã¯ã Firebase ã³ã³ãœãŒã« ã§ã¢ããªã«æ¥ç¶ããããã® Firebase ãããžã§ã¯ããæ°èŠäœæããŸãã äœæããã¢ããªãFirebaseã«ç»é²ãã ãããžã§ã¯ãæŠèŠ > iOS+ ã¢ã€ã³ã³ > èšå®ã¯ãŒã¯ãããŒã«é²ã¿ãŸãããããšãApple ãã³ãã«IDã®å
¥åãæ±ããããŸãã ããã²ãŒã¿ãŒãšãªã¢ã®äžã®ãããžã§ã¯ãå > TARGETS ã®ãããžã§ã¯ãå > General ã¿ãã§Apple ãã³ãã«IDã確èªã§ããŸãã èšå®ãã¡ã€ã«ã®ããŠã³ããŒã ããŠã³ããŒããã GoogleService-Info.plist ãã¡ã€ã«ãXcode ãããžã§ã¯ãã®ã«ãŒãã«ç§»åãããã¹ãŠã®ã¿ãŒã²ããã«è¿œå ããŸãã Firebase SDKã远å ãã Firebase SDKã¯ããã€ãã€ã³ã¹ããŒã«æ¹æ³ããããŸãããä»åã¯CocoaPodsãå©çšããŸãã Podfileãäœæãã ãããžã§ã¯ããã£ã¬ã¯ããªã®ã«ãŒãããæ¬¡ã®ã³ãã³ãã§ãPodfileãäœæããŸãã pod init Podfileã«FirebaseAnalyticsã远å ãã ã¢ããªã§äœ¿çšãã'Firebase/Analytics'ãPodfileã«è¿œèšããŸãã # Add the Firebase pod for Google Analytics pod 'Firebase/Analytics' # For Analytics without IDFA collection capability, use this pod instead# pod âFirebase/AnalyticsWithoutAdIdSupportâ # Add the pods for any other Firebase products you want to use in your app# For example, to use Firebase Authentication and Cloud Firestore # pod 'Firebase/Auth' # pod 'Firebase/Firestore' Podãã€ã³ã¹ããŒã«ãã pod install ãå®è¡ããŸãããã ããM1 Macã ãšäžæãã€ã³ã¹ããŒã«ã§ããªãããšãããããã§ãã ç§ã®ç°å¢äžã§ã¯ã¿ãŒããã«ã®ã¢ãŒããã¯ãã£ã«äŸåããŠããã®ã§ä»¥äžã®ããŒãžãåèã«ãã¿ãŒããã« > å³ã¯ãªãã¯ã§ãæ
å ±ãèŠãã > ãRosettaã䜿çšããŠéãã ã«äºåã«ãã§ãã¯ãå
¥ããŸããããããããšã§ãåé¡ãªãPodãã€ã³ã¹ããŒã«ã§ããŸããã ãåèãM1 Macã§pod installãå®è¡ãã pod install Podã€ã³ã¹ããŒã«ãå®äºãããšã .xcworkspace ãã¡ã€ã«ãäœæãããŸãã以é㯠.xcworkspace ãã¡ã€ã«ããXcodeãããžã§ã¯ããéããŸãã åæåã³ãŒãã远å ãã ã¢ããªèµ·åæã« Firebase ãæ¥ç¶ããã«ã¯ãXcodeãããžã§ã¯ãã®@mainã¢ããªãã¥ãŒã·ã§ã³ã®æå®ã®å Žæã«æå®ã®ã³ãŒãã远å ããŸãã import SwiftUI import Firebase //è¿œèš @main struct testApp: App { var body: some Scene { WindowGroup { ContentView() } } init() { FirebaseApp.configure() //è¿œèš } } ããã§ãFirebase SDKã®è¿œå ã¯å®äºã§ãã 3.GA4ã®DebugViewã§ãã°æ€èšŒãè¡ã æåŸã«ãGA4ã§ãã°æ€èšŒãè¡ããŸããæ©éãã°æ€èšŒãšãããããšããã§ãããäºåã«ããã€ãèšå®ãè¡ãå¿
èŠããããŸãã Debug Modeãæå¹ã«ãã Xcodeãéããã¡ãã¥ãŒã㌠> Product > Scheme > Edit Scheme > Run > Argumentsã®Arguments Passed On Launchã«FIRDebugEnabledã远å ããããšã§ãDebug Modeãæå¹ã«ããŸãã Firebaseã®èªåãã°ååŸããªãã«ããŠæåãã°ååŸãèšå®ãã ä»åSwiftUIãšã®çžæ§ãããããŸããããèªåãã°ååŸã§ã¯ç»é¢é·ç§»ã§screen_viewã€ãã³ããé£ãã ãé£ã°ãªãã£ããããŠããã®ã§ãæåã§ãã°ååŸãããå®è£
ã«ããŠããŸãã Info.plist ãã¡ã€ã«ã«ä»¥äžã远å ããããšã§èªåãã°åéããªãã«ããŸãã KeyïŒFirebaseAutomaticScreenReportingEnabled ValueïŒNO(Boolean) ãããã¯æã«Xcodeã®Report Navigatorã§ä»¥äžã®ãããªãã°ã確èªã§ããã°ãèªåãã°åéããªãã«ãªã£ãŠããŸãã Analytics screen reporting is disabled. UIViewController transitions will not be logged. ãã°æ€èšŒ Debug Viewã§screen_viewã€ãã³ããbuttun_tapã€ãã³ããèšæž¬ãããŠããã®ãåãããŸããåé¡ãªããã°ãé£ãã§ããŸããæ€èšŒå®äºã§ãã BigQuery飿º BigQueryã«é£æºããŠãšã¯ã¹ããŒããããŠãããã°ã確èªããŸãããæ·»ä»ç»åã®ã«ã¹ã¿ã ã€ãã³ãbutton_tapã®ãã°ã¯å®è£
ããéããbutton_name ã«èšå®ããå€ hoge ãæ ŒçŽãããŠããŸãã ãããã« ä»åç¡äºã«ã¢ããªã宿ãããŠãã°æ€èšŒãè¡ãããšãã§ããŸãããç§èªèº«ããã°ã©ãã³ã°æªçµéšã ã£ããããåãçµãåã¯åãããªãããšã ããã§ãããå
·äœçã«ã¯ãããã°ã©ãã³ã°ã®åºç€ããªãããšã©ãŒã®è§£æ±ºæ¹æ³ãåãããŸããã§ãããä»ã«ãã¿ãŒããã«ãGitHubã§äœãã§ããã®ãããç¥ããŸããã§ããã ããããUdemyã§åŠç¿ããããåãããªãããšãäžã€äžã€æ€çŽ¢ãšã³ãžã³ã§èª¿ã¹ãããšã§åé¡è§£æ±ºããããšãã§ããŸãããã¢ããªå¶äœã®å Žé¢ã¯ãšã©ãŒã®é£ç¶ã§ãããããšã©ãŒã解決ããç¬éãæã楜ããã£ãã§ãã ãããŠãäœãåãçµãã«ããŠããããã°ã§ããããšèªä¿¡ãã€ãããã«ãªããŸããããããããããŸããŸãªããšã«ãã£ã³ã¬ã³ãžããŠãããŸãã ã©ãªããã®åèã«ãªãã°å¹žãã§ãã
ã¯ãããŸããŠãmediba FEãšã³ãžãã¢ã®æ¥ã§ãã æè¿ç«ãã³ãé¿ãäžæã«ãªã£ãŠããã®ã§ãç«ãå°ãããŠããŸãã React NativeåèŠ ãããã§èª¿ã¹ãŠã¿ãŠã第äžå°è±¡ã¯ã坿ããã£ããã§ãã ãã®ä»ã«æããå°è±¡ã¯äžèšã§ãã facebookã®cross-platformãã¬ãŒã ã¯ãŒã¯ã§ã1åæžãããAndroidãiOSãWebå
šéšåãã ããã React NativeïŒä»¥äžRNïŒãšããååä»ããªã®ã§ãReactéçºè
ã«ãšã£ãŠã䜿ããããã ãã ãšããæµ
ãèªèã§ãããŒã ã¡ã³ããŒãšäžç·ã«RNã®ãããžã§ã¯ããæžããŠã¿ãŸããã React Nativeæ¯ãè¿ã ããçšåºŠã³ãŒããæžããŠã¿ããšã以äžã®äºã«æ°ãä»ããŸããã ããŒãžã§ã³ã¢ãããæ©ã æè¿ã®ãªãªãŒã¹ãèŠããš1幎é3åã®ã¡ã€ã³ããŒãžã§ã³ããããªãªãŒã¹ãããŠãRNã®ããŒãžã§ã³ç®¡çã課é¡ã«ãªããããç¹ã«ãã£ããã¢ããã«ã¯ãäºææ§ã®åé¡ãç®ã®åã« debugã®é£ãã Webéçºãšæ¯ã¹ããšãRNã§ããã¿ãçã£èµ€ãªç»é¢ã®ãšã©ãŒç»é¢ããããããã®ã¡ãã»ãŒãžã ãã§ãããã³ãããã€ãã£ããã®ãšã©ãŒã®å€æã¯é£ãã èŠçŽ ã®é«ããã¹ã¯ãªãŒã³ã®é«ããè¶
ãããã¹ã¯ããŒã«ã§ããªã Webã ãšçãŸãã€ãã§ã¹ã¯ããŒã«ã§ãããã©ãRNã®å Žåäžçªå€åŽã«ã¹ã¯ããŒã«å¯èœã®ãšã¬ã¡ã³ãã§wrapããŠãããªããš iOSãšAndroidã«ãããŠã®éã ããçšåºŠRNããã®éããåããŠãããŠãŸãããããããã®ç°å¢ã«äŸåããåŠçãããïŒå€éšlibã§æžãå ŽåãïŒ ãªã¹ãã®éžæ RNã®ãªã¹ããå
ã
listViewãšflatListäºã€ããã£ãŠãlistviewã¯æ§èœçãªåé¡ã§æŸæ£ãããŠãflatListãæšå¥šãããŠãŸãïŒå®éã«ã«ãŒã»ã«ãäœã£ãéã«å°ã£ãŠãïŒ ã€ãŸããRNã¯äŸåå¿ã®åŒ·ãåã§ããã å°è±¡çãã€ã³ã RNãè§Šã£ãŠã¿ãŠãäžçªè峿·±ããšãããšãããšãnative codeã§æžããSDKãæ±ããéšåã§ããããããã Native Module Bridging ãšãããã®ã§ãã åè¿°ã®éãããçšåºŠRNãiOSãšAndroidã®éããåããŠãããŠãŸãããããããã®OSã«äŸåããAPIã¯JSã§ã®æ±ãã¯äžå¯ãªãã®ãããããããã¯ããé«ãããã©ãŒãã³ã¹çããã«ãã¹ã¬ããçã«äœãããå Žåãnative moduleãä»ããŠãããå®çŸã§ããŸãã å®éæãåãããŠã å
¬åŒããã¥ã¡ã³ããã¿ãªãããèªåãªãã«ç°¡åãªãhello-worldããäœã£ãŠã¿ãŸãããïŒåŠæ ¡ã§JavaãåŠãã§ãã®ã§ãå人çã«èŠªå㪠Android ãéžãã ^^ïŒ ã¹ãããïŒ ç°å¢èšå® ãªããšãªãåãnative codeæžã RNãä»ããŠãnative moduleãšããŠãJSåŽã«ã«æ«é²(expose)ãã JSåŽã§åŒã³åºã ç°å¢èšå® å
¬åŒããã¥ã¡ã³ã ã«æ²¿ã£ãŠç°å¢èšå®ã§ããŸããJavaScript(以äžJS)ãTypeScript(以äžTS)äž¡æ¹äœããŸããã èªåã¯TSã®ãã³ãã¬ãŒããäœããŸãã(TSæé«) ãªããšãªãåãnative codeæžã ç°å¢èšå®çµãããŸããããäžèšã®androidã®ãã©ã«ãã§äœæ¥ãããŠãããŸãïŒèªåã¯Javaã®æ§æããŸãèªä¿¡ãªããããAndroid Studioã§androidãã©ã«ããŒãéããŠã³ãŒããæžããŠããwïŒ android/app/src/main/java/com/awesomeproject ã®é
äžã§ HelloModule.java ãšããæ°èŠJavaãã¡ã€ã«ãäœããŸãã ãã¡ã€ã«ã®äžèº«ã¯ãããªæãïŒ public class HelloModule extends ReactContextBaseJavaModule {   private static ReactApplicationContext reactContext;   HelloModule(ReactApplicationContext context) {     super(context);     reactContext = context;   }   public static void setTimeout(Runnable runnable, int delay){     new Thread(() -> {       try {         Thread.sleep(delay);         runnable.run();       }       catch (Exception e){         System.err.println(e);       }     }).start();   }   @ReactMethod   public void sayHelloToPopUp(String name) {     Toast.makeText(reactContext,"Hello World,"+name,Toast.LENGTH_LONG).show();   }   @ReactMethod   public void sayHelloAfterThreeSecond(String name, Promise promise) {     setTimeout(()->promise.resolve("Hello after 3 seconds,"+name),3000);   }   @NonNull   @Override   public String getName() {     return "HelloModule";ã//ãã®åœåã§NativeModulesã«è¿œå   } }; ãšãããã詊ãã«ãäžèšäºã€ã®é¢æ°ãäœã£ãŠã¿ãŸããã Androidã®Toastã䜿ã£ãŠåºåã§ãã sayHelloToPopUp Promiseãè¿ã sayHelloAfterThreeSecond App(JSåŽ)ã«æ«é²(expose)ãã initåŸã«èªåçæããã android/app/src/main/java/com/awesometsproject/MainApplication.java ã®äžèº«ãèŠãŠã¿ããš protected List getPackages() {      @SuppressWarnings("UnnecessaryLocalVariable")      List packages = new PackageList(this).getPackages();      // Packages that cannot be autolinked yet can be added manually here, for example: â» Â Â Â Â // packages.add(new MyReactNativePackage()); âãã®è¡ãè§£æŸ Â Â Â Â Â return packages;     } æ¢ã«çšæããŠãããPackageåã§packageãäœããŸããäžèšã®ãã¡ã€ã«ãšåããã©ã«ããŒé
äžã§ MyReactNativePackage.java ã®ãã¡ã€ã«ãäœæããnativePackageäœããNativeModuleã«å
çšäœæããHelloModuleã远å ããã°å®æã§ãã public class MyReactNativePackage implements ReactPackage {   @NonNull   @Override   public List createViewManagers(@NonNull ReactApplicationContext reactContext) {     return Collections.emptyList();   }   @NonNull   @Override   public List createNativeModules(       @NonNull ReactApplicationContext reactContext) {     List modules = new ArrayList<>();     modules.add(new HelloModule(reactContext));     return modules;   } } JSåŽã§åŒã³åºã æåŸã®äžæ©ã¯ãApp.tsxã§äœ¿ãããšã§ããã  import { NativeModules } from 'react-native';  ãŸãNativeModulesãimport,ããããå
çšäœã£ã sayHelloToPopUp ãš sayHelloAfterThreeSecond ãåŒã³åºããŸãïŒ Â const { HelloModule } = NativeModules  const sayHello = React.useCallback((words)=>{   HelloModule.sayHelloToPopUp(words)  },[])  const sayHelloThreeSecondsLater = React.useCallback(()=>{   HelloModule.sayHelloAfterThreeSecond('lalalalala').then((res)=>sayHello(res))  },[]) ... <button title="{"> æåŸãrootã§yarn androidããã°ãèµ·åãåŸ
ã¡ãã·ãã¥ã¬ãŒã¿ãŒãç«ã¡äžãã£ãŠã¢ããªã€ã³ã¹ããŒã«å®äºãã¢ããªã§pressãã¿ã³ãããã 3ç§åŸã«æ·»ä»ç»åã®ããŒã¹ããåºãŠããŸã ææ³ RNã®ãããªã¯ãã¹ãã©ãããã©ãŒã ã®ãã¬ãŒã ã宣äŒããããã«ããäžåæžãããã©ã®ãã©ãããã©ãŒã ã§ãåããããšããçæ³ããããã å®éã«ãããžã§ã¯ããäœãã«åœãã£ãŠããã€ãã£ãã¢ããªãããã³ããå
šéšçè§£ããäžäººã§ã®iOS,AndroidãšWebå
šãŠã®ã³ãŒããæžããããšã¯ããããªãã ãããRNãæ¶ãæ©ã«ããã€ãã£ãããŒã ãšããã³ãããŒã ã飿ºããæ¬æ°ãªããã°ïŒB.I.GïŒããã³ãããŒã ãçã¿åºããã§ã¯ãªãã§ããããã ããšããã®éããçæ³ãªãè
ã«æåãªãã^^
ããã«ã¡ã¯ãEng6G ããã¯ãšã³ããšã³ãžãã¢ã®åå±( @hrktcy )ã§ãããããã瀟äŒäºº2幎ç®ãšããããšã§ææ¥ã®æµãããšãŠãæ©ãæããŸãã ã¯ããã« çŸåšéçºäžã®ãããã¯ãã§ãAPI ãªã¯ãšã¹ããã©ã¡ãŒã¿ã«å«ãŸããã客æ§ã®å人æ
å ±ãããŒã¿ããŒã¹ã«æå·åããŠæ ŒçŽããããã«AWS Key Management Service(KMS) ãå°å
¥ããããšã«ãªããŸãããå°å
¥ããã«ããããKMS ã§ã®æå·åã®ãªã¯ãšã¹ãããã©ãŒãã³ã¹ããéçºäžã®ã·ã¹ãã ã«å®ããSLA ã«èãããæ§èœããæ€èšŒããå¿
èŠããããŸãããæ¬èšäºã§ã¯ãã®çµæãå
±æããããšæããŸãã æ€èšŒé
ç® åºåãããã®ã¯ä»¥äžã®3ã€ã§ãã å¹³åæå·ååŠçæé(ms) åæå·ååŠçæéãæé ã«ãœãŒãããéã®90ããŒã»ã³ã¿ã€ã«å€(ms) æå€§æå·ååŠçæé(ms) ç°å¢ ããŒã«ã«ç°å¢ã§Golang ã§æ€èšŒçšã®ãµã³ãã«ã³ãŒããæžããŸãããããŠã¯ãã¹ãã©ãããã©ãŒã ãã«ãã«ãã£ãŠçæããããã€ããªãã¡ã€ã«ãS3 ã«PUT ããEC2ããå®è¡ããŸãã èšèª Golang SDK aws-sdk-go-v2 å®è¡å Žæ EC2(t2.micro/x86) æå·åããæååãäœæãã颿°ãå®çŸ©ãã ãŸããæ€èšŒçšã®æåå[0-9a-zA-Z](32æå)ãçæãã颿°ãå®çŸ©ããŸããçæã«ã¯ math/rand ããã±ãŒãžãçšããŠã©ã³ãã ãªæååãçæããããã«ããŸããçææ°ã¯ã³ãã³ãã©ã€ã³åŒæ°ããæå®ã§ããããã«ããŠãããŸãã package main import ( "math/rand" ) func randomStr(n int) string { letters := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" lettersLen := len(letters) dst := make([]uint8, n) for i := 0; i < n; i++ { l := rand.Intn(lettersLen - 1) dst[i] = letters[l] } return string(dst) } æå·ååŠçãè¡ã颿°ãå®çŸ©ãã æå·ååŠçãè¡ãexec 颿°ãå®çŸ©ããŸãããã®é¢æ°ãgoroutine ã§äžŠè¡åŠçããããã«ããŸããsync.waitGroup ã®Done() ãdefer ããããšã§ãåŠçã®æåŸã«å®äºãç¥ãããããã«ããŠãããŸãã var wg sync.WaitGroup var keyID = "*******" // ãã¹ã¿ãŒããŒã®KeyID var client *kms.Client // data çµææ ŒçŽçšæ§é äœ type data struct { Encrypted []byte ProcessTime time.Duration } func exec(plain string, results *[]data) { defer wg.Done() // èšæž¬éå§ start := time.Now() // keyIDãšæå·åããæååã代å
¥ input := &kms.EncryptInput{ KeyId: &keyID, Plaintext: []byte(plain), } // æå·åãªã¯ãšã¹ã output, err := client.Encrypt(context.TODO(), input) if err != nil { fmt.Printf("Got error encrypting data:%v\n", err) return } // æå·åæååãšåŠçæéãdataåã®å€æ°ã«ä»£å
¥ãã result := data{ Encrypted: output.CiphertextBlob, ProcessTime: time.Since(start), } *results = append(*results, result) } main 颿°ãå®è£
ãã åè¿°ã®é¢æ°ãçšããŠmain 颿°ãå®è£
ããŸããmain 颿°ã§ã¯randomStr 颿°ã§çæããæååãæ ŒçŽããé
åãçšæããKMS ã¯ã©ã€ã¢ã³ããçæããŠããæå·ååŠçãgoroutine ã§äžŠè¡åŠçãããŸãããªããfor ã«ãŒãã®äžã§time.Sleep() ãããããšã§TPS ã調æŽã§ããããã«èšå®ããã«ãŒãåŠçãçµäºãããæ€èšŒé
ç®ãèšç®ããŠåºåããããã«ããŸãã package main import ( "context" "flag" "fmt" "log" "math/rand" "sort" "sync" "time" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/kms" ) // data çµææ ŒçŽçšæ§é äœ type data struct { Plain string Encrypted []byte ProcessTime time.Duration } var wg sync.WaitGroup var keyID = "*******" // KeyID var client *kms.Client var num = flag.Int("num", 100, "æå·åå®è¡åæ°") var interval = flag.Int("interval", 1, "-interval ") // randomStr ã©ã³ãã æååãçæãã颿° func randomStr(n int) string { letters := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" lettersLen := len(letters) dst := make([]uint8, n) for i := 0; i < n; i++ { l := rand.Intn(lettersLen - 1) dst[i] = letters[l] } return string(dst) } // exec 䞊ååŠçãã颿° func exec(plain string, results *[]data) { defer wg.Done() // èšæž¬éå§ start := time.Now() // keyIDãšæå·åããæååã代å
¥ input := &kms.EncryptInput{ KeyId: &keyID, Plaintext: []byte(plain), } // æå·åãªã¯ãšã¹ã output, err := client.Encrypt(context.TODO(), input) if err != nil { fmt.Printf("Got error encrypting data:%v\n", err) return } // æå·åæååãšåŠçæéãdataåã®å€æ°ã«ä»£å
¥ãã result := data{ Encrypted: output.CiphertextBlob, ProcessTime: time.Since(start), } *results = append(*results, result) } func main() { flag.Parse() // æ€èšŒçšæååæºå maxStrLen := 32 plainList := make([]string, *num) for i := range plainList { plainList[i] = randomStr(maxStrLen) } // KMSã®ã¯ã©ã€ã¢ã³ããäœæ loadOptions := []func(*config.LoadOptions) error{config.WithRegion("ap-northeast-1")} sdkCfg, err := config.LoadDefaultConfig(context.TODO(), loadOptions...) if err != nil { panic("configuration error, " + err.Error()) } client = kms.NewFromConfig(sdkCfg) // æå·ååŠçå®è¡ results := make([]data, 0) for _, v := range plainList { wg.Add(1) go exec(v, &results) time.Sleep(time.Millisecond * time.Duration(*interval)) } // çµäºãåŸ
〠wg.Wait() // çµæå€å® success := len(results) if success < 1 { log.Fatal("empty success result") } // ãããããæé ã§ãœãŒãããŠãã sort.Slice(results, func(i, j int) bool { return results[i].ProcessTime < results[j].ProcessTime }) // å¹³åæå·ååŠçæéãèšç® total := int64(0) for _, v := range results { total = total + v.ProcessTime.Milliseconds() } fmt.Printf("avg:%dms\n", total/int64(success)) // 90ããŒã»ã³ã¿ã€ã«å€ãèšç® percentile := int(float64(success)*0.9 - 1) fmt.Printf("Percentile:%dms\n", results[percentile].ProcessTime.Milliseconds()) // æå€§æå·ååŠçæéãèšç® fmt.Printf("max:%dms\n", results[success-1].ProcessTime.Milliseconds()) } æ€èšŒçµæ 500(req/sec)ã§400åã®æååæå·åãè¡ã£ãå Žå avg(ms) 90 percentile(ms) max(ms) 9 9 68 500(req/sec)ã§1000åã®æååæå·åãè¡ã£ãå Žå avg(ms) 90 percentile(ms) max(ms) 7 8 61 æå·ååŠçãå¢ãããå Žåã§ãåæå·ååŠçæéã«å€§ããªå·®ã¯çãŸããŸããã§ãããããããæå€§æå·ååŠçæéã¯90ããŒã»ã³ã¿ã€ã«å€ããã倧å¹
ã«æéãããã£ãŠããããšãããããŸããããã®å€ã¯ååæå·ååŠçæéã®å€ã§ããã®ã§ã2åç®ä»¥éã¯KMS ã¯ã©ã€ã¢ã³ãã䜿ãåããŠãããååã¯KMS ã¯ã©ã€ã¢ã³ããèªã¿èŸŒãã§ããåæéãããã£ãŠããã®ã§ã¯ãªãããšããæšæž¬ãããŸããã æå·ååŠçæ¯ã«KMSã¯ã©ã€ã¢ã³ããèªã¿èŸŒãã§ã¿ããã©ãã main 颿°å
ã§è¡ã£ãŠããKMS ã¯ã©ã€ã¢ã³ãäœæåŠçãexec 颿°å
ã«ç§»åããæå·åãªã¯ãšã¹ãã®éœåºŠã¯ã©ã€ã¢ã³ããäœæããããã«å€æŽããŠãªã¯ãšã¹ãããã©ãŒãã³ã¹ãæ€èšŒããŠã¿ãŸãã åæ§ã®æ¡ä»¶ã§æ€èšŒã詊ã¿ããšããã以äžã®IMDSã®èªèšŒãšã©ãŒãçããŠããŸãæå·åãè¡ããŸããã§ããã Got error encrypting data:operation error KMS: Encrypt, failed to sign request: failed to retrieve credentials: no EC2 IMDS role found, operation error ec2imds: GetMetadata, http response error StatusCode: 429,request to EC2 IMDS failed [åè]:429 Too Many Requests ããã§ãæå·ååŠçæ°ãæžãããŠåŠçé床ãèšæž¬ããŠã¿ãŸãã 500(req/sec)ã§10åã®æååæå·åãè¡ã£ãå Žå avg(ms) 90 percentile(ms) max(ms) 52 65 73 500(req/sec)ã§100åã®æååæå·åãè¡ã£ãå Žå avg(ms) 90 percentile(ms) max(ms) 749 2113 2158 åŠçæ°ãå¢ãããšå¿çæéãé·ããªãããšãåãããŸãããTPS ãäžããŠã¿ããã©ããªãã§ããããã 100(req/sec)ã§100åã®æååæå·åãè¡ã£ãå Žå avg(ms) 90 percentile(ms) max(ms) 28 39 54 TPS ãäžãããšååŠçæéãã ãã¶èœã¡çããŸããã ãŸãšã KMS ã¯ã©ã€ã¢ã³ãã䜿ãåããã¿ãŒã³ã§ã¯ååæå·ååŠçæéã«å°ãæéãããããã®ã®ãæå·ååŠçæ°ãå€ããŠãååŠçæéã«å€§ããªå·®ã¯çãŸããŸããã§ãããäžæ¹ãéœåºŠKMS ã¯ã©ã€ã¢ã³ããèªã¿èŸŒãŸãããã¿ãŒã³ã§ã¯ãå¿çæéãé·ããªã+倧éã®æå·ååŠçãè¡ãå Žåã¯TPS ãäžããå¿
èŠãããããã§ãã
åãã« ããã«ã¡ã¯ããšã³ãžãã¢ã®éåŽã§ããæè¿ã¯çŸå Žã§ãããã¯ãã®éçºãè¡ãã€ã€ã å
ŒåãšããŠCTOæºåå®€ã«æå±ãããã¯ãªãŒããšããããŒã«ãæã¡ãè€æ°ã®ãããã¯ãã«ãŸããããã¯ãããžãŒã»ã³ã¿ãŒã®èª²é¡ã æè¡çãªç¹ã軞ã«ããªãã解決ã«åããŠåãçµãã§ããŸãã â»åèèšäºïŒ 2020幎床ãšã³ãžãã¢çµç¹ã«ã€ã㊠| mediba Creator à Engineer Blog æ¬èšäºã§ã¯ãããã¯ãªãŒãã®åãçµã¿ãšããŠ21å¹ŽåºŠäžæã«æ€èšãåãçµã¿å§ãã ãæ°èŠéçºæã®æè¡éžå®ã®æéã ã«ã€ã㊠ãã®å
容ãšèæ¯ããäŒããŠããŠãããŸãã ç¹ã«ä»åŸãšã³ãžãã¢ãšããŠåŒç€Ÿã«å
¥ç€Ÿãæ€èšé ããæ¹ã«åããŠã ã©ã®ããã«æè¡ãšçµç¹ã«ã€ããŠèããŠãããããäŒããŠåºæ¥ãã°ãšæããŸãã ãããŸã§ã®æè¡éžå®æ¹é ãããŸã§ã¯ãæ°èŠéçºæã«ã¯åãããã¯ãæ¯ã«å©çšããæè¡ïŒããŒã«ã»ãœãããŠã§ã¢)ãéžå®ããŠæ¥ãŸããã åãããã¯ãæ¯ã«å©çšããæè¡ïŒããŒã«ã»ãœãããŠã§ã¢)ãéžå®ããããšã§ã ãããã¯ãããã®ããŒã ã«ãã£ãéçºãããæ°ãããã®ãç©æ¥µçã«åãå
¥ããããšãç®æããŠããŸããã ãã®æ¹éã§æ°å¹Žãã¡ãŸãããããã®ç¹ã¯éæã§ããŠããŸããã ãã ããã®äžã§ç¹ã«éçšä¿å®ã«ãããŠäžæããããªãç¹ã»æªã¿ãçãŸããŠããŸããã ä»åãæ°èŠéçºæã®æè¡éžå®ãã®æéã«ãŠãéšåçã«å©çšããæè¡(ããŒã«ã»ãœãããŠã§ã¢ïŒã®æéãèšããããšã«ãã£ãŠ è€æ°ã®ãããã¯ãã«ãããŠã暪æçã«éçšä¿å®ãããå¹ççã«å質é«ãè¡ãããšãç®æãããã®ã«ãªããŸãã æ°èŠéçºæã«ãããæè¡éžå®ã®æé ä»ååãæ±ºãããæ°èŠéçºæã®æè¡éžå®ãã®æéã«ã€ããŠã ãã®ãŸãŸå
¬éã¯åºæ¥ãŸããã®ã§ã3ç¹ã«ãã€ã³ããçµã£ãŠèª¬æããŸãã â æé1. 以äžã®é åã«ãããŠãåºæ¬ãšãªãããŒã«ã»ãœãããŠã§ã¢ãæéãå®çŸ©ãã ãããªãã¯ã¯ã©ãŠã ã³ã³ãã¥ãŒãã£ã³ã° ããã¯ãšã³ãã¢ããªã±ãŒã·ã§ã³éçºã®ããã°ã©ãã³ã°èšèª ããŒã¿ããŒã¹ CI/CDç°å¢ ããã§ã¯å
šãŠèšèŒããŸãããã äŸãã°ããããªãã¯ã¯ã©ãŠããã«ãããŠã¯ãAWSããå©çšããããšåºæ¬ãšããããšãã£ãå
容ã§ãã ãŸããããã«æããé å以å€ã®ãã®ã§æ€èšäžã®ãã®ããããŸãã äŸãã°ããã€ãã£ãã¢ããªã±ãŒã·ã§ã³ãã«ã€ããŠã§ããã 瀟å
ã§éçºéçšå®çžŸããããŸããæ
åœããããŒã ãäžã€ã«ãªã£ãŠããããšããããæ€èšããŠããæ®µéã«ãªããŸãã é åãããŒã«ã»ãœãããŠã§ã¢ã®éžå®ã«åœãã£ãŠã¯ã ãããã¯ãã«ãšã£ãŠã³ã¢ãšãªãæè¡é åããã©ã€ããµã€ã¯ã«ã¯ã©ã®ããããèŠèŸŒãã§ããããªã©éã¿ã æ¢åã·ã¹ãã ã§ã®æ¡çšäºäŸã»æ¢åã¡ã³ããŒã®ã¹ãã«ã»ãããéèŠèŠãéžå®ãè¡ããŸããã â æé2.ãæé1ãã«èšèŒãããŠããªãå Žåã¯ãã»ã³ã¿ãŒå
ã§è©±ãåãæ±ºå®ãã ä»åŸæ°èŠéçºæã®èŠæ±èŠä»¶ã«ãã£ãŠã¯ããæé1ãã§å®çŸ©ãããã®ã§ã¯å®çŸåºæ¥ãªãå¯èœæ§ããã¡ãããããŸãã ãã®å Žåã¯ãæ°èŠéçºã®æ
åœããŒã ã ãã§ã¯ãªããä»ã®éçºããŒã ãå«ãã»ã³ã¿ãŒå
ã§è©±ãåã£ãŠæ±ºå®ããŠãããŸãããã®äžã§ãå°å
¥äºåŸã®ãã£ãŒãããã¯ãè¡ãåè©äŸ¡ããŸãã â æé3.ãæé1ãã®å
容ã¯1幎çšåºŠã®ã¹ãã³ã§èŠçŽããè¡ã ãæé1ãã®å
容ããé·ã幎æãçµããšç¶ç¶çãªã¡ã³ããã³ã¹ã«åé¡ãåºããã ããè¯ã代æ¿ã®ããŒã«ã»ãœãããŠã§ã¢ãåºãŠããå ŽåããããŸãã ãããã£ãã¡ãªããã»ãã¡ãªãããè©äŸ¡ããã«æè¡ã硬çŽåãããããšã¯æãã§ã¯ããªãããã 宿çã«å
容ãè©äŸ¡ã»èŠçŽããŠãããŸãããããšããããšã§ãã ãããæéã軞ã«ã ãæšªæçãªæ€èšâ詊è¡âè©äŸ¡ãã®ãµã€ã¯ã«ãç®æãããšã骚åã«ããããŸãã medibaã«ãããéçºã®ç¹åŸŽ ããã§ã¯ãmedibaã«ãããéçºã®ç¹åŸŽãåãäžãã ãæ°èŠéçºæã®æè¡éžå®ãã®èæ¯ã説æããŸãã 倧ããªç¹åŸŽãšããŠã äžã€ã®ãããã¯ã(ã·ã¹ãã ïŒã®æ°èŠéçºããéçšïŒã°ããŒã¹ãã§ãŒãºïŒã»ä¿å®ãŸã§ã 瀟å
ã§äžæ°é貫ã§å¯Ÿå¿ããããšãæãããŸãã ãŸãããæ°èŠéçºãããéçšããå°éã«ããããŒã ã¯ãªãã ãããŸã§ãããã¯ãæ¯ã§ã®ããŒã ã§æ
åœããã®ãç¹åŸŽçã§ãã 瀟å
ã§æ±ããããã¯ãïŒãµãŒãã¹ïŒæ°ã¯æ°åã»ã©ããã å¿
ç¶çã«ããŒã çµæã®æ©äŒãå€ããªããŸãã äžèšã®å³ã䜿ã£ãŠèª¬æããŸãã äŸãšããŠããããã¯ãAãšBã®æç³»åã§ãæ°èŠéçºããéçšããä¿å®ãã®ãã§ãŒãºãš ãã®æç¹ã§å¿
èŠãšããããšã³ãžãã¢ãå³ç€ºããŠã¿ãŸããã ãããã¯ãBã®éçšãã§ãŒãºéå§æã«ã€ããŠèããŠã¿ãŸãã ç°¡åã®ããã«ãããã¯ãAã®éçšã¡ã³ããŒãããããã¯ãBã®éçšãæ
ãããšã«ãªãå Žåã ãããã¯ãAãšBã®æ¡çšæè¡ã倧ããç°ãªãå Žåã ãã®æè¡çãªç¿åŸããªã³ããŒãã£ã³ã°ãªã©ã«å€§ããæéãåãããŠããŸãã æ¬æ¥éçšïŒã°ããŒã¹ãã§ãŒãºïŒã«æåŸ
ããããããªç©æ¥µçãªéçºãã·ã¹ãã ã®å®å®æ§ãé«ããåãçµã¿ãéæã§ããªãã ãããã¯ããããããŒã çµæãé£ãããšãã£ã課é¡ãçºçããŠããŸããã ãã®ãããªèæ¯ããäžè¿°ã®ãæ°èŠéçºæã®æè¡éžå®ãã®æéãäœæããŸããã æåŸã« ããžã§ã³ïŒãè¯ããã®ããå±ãç¶ãã ãã¯ãããžãŒã»ã³ã¿ãŒã®ããžã§ã³ãšããŠãããè¯ããã®ããå±ãç¶ãããããããŸãã æ¥ã
çŸå Žã§ã®æ¥åãè¡ã£ãŠãããšã çæçãªçŽæãèªããŒã ã®ã¡ã³ããŒã«ããæèãéäžããããšãå€ããèŠç¹ãçããªããã¡ã§ãã æã«ã¯ããèšã£ãããžã§ã³ã«ç«ã¡è¿ããé·æçã«çµç¹å
šäœãæ¥çå
šäœã«ãç®ãåãã€ã€ ãè¯ããã®ããå±ãç¶ããããã«ãèªåãã¡ã䜿ãæè¡ãããè¯ãå€åãããŠããããšã¯ã çµç¹ãšããŠãå人ãšããŠãæŽãªãæé·ã«ç¹ãããšä¿¡ããŠããŸãã ããžã§ã³ã®å®çŸã®ããã«ã å°éã«äžæ©ãã€äžç·ã«åãçµãã§é ãããšã³ãžãã¢ã®æ¹ã®å¿åãmedibaã§ã¯ãåŸ
ã¡ããŠãããŸãã
mediba Advent Calendar 2021 ã® 18 æ¥ç®ã®èšäºã§ãã ããã«ã¡ã¯ããšã³ãžãã¢ã®äžçïŒ @yn2011 ïŒã§ããæè¿ã¯ Switch ã®æå§«ã§çŽæ»ã®éçŒã«ã€ããŠåŠãã§ããŸãã åãã« ãããã¯ããæ°èŠã«éçºããéã«ãã©ã㪠Lint ããŒã«ãå°å
¥ããã©ã®ãããªèšå®ã§å©çšãããã¯æ©ãããšãå€ãã§ããæçµçã«ã¯ããŒã ã¡ã³ããŒãšè°è«ãããŠæ±ºããŠããå¿
èŠããããŸããã瀟å
å€ã®ä»ã®ãããã¯ãã§ã©ã®ããã«ããŠãããåèäºäŸã欲ããå ŽåããããŸããæ¥åã§éçºãããããã¯ãã®ã³ãŒãããŒã¹ã¯ç€Ÿå€ã«å
¬éãããããšã¯å°ãªããããä»ç€Ÿã§ã©ã®ãã㪠Lint ããŒã«ãå°å
¥ããŠããã®ããç¥ãæ©äŒã¯å°ãªãã§ãã ãããã£ãèæ¯ãããçŽè¿ã®ãããã¯ãéçºã«ãã㊠â ã©ã㪠Lint ããŒã«ãå°å
¥ããŠããããâ¡ ç¹ã«å·¥å€«ããŠããèšå®ã¯äœãã ãšãã Lint ã«ãã©ãŒã«ã¹ããå
å®¹ãæžãããã©ãã ãããšèããä»åã®èšäºã®ããŒããšããŸããã æšå¹ŽããåŒãç¶ããmediba ã®ãããã¯ãã§ã¯ Next.js ã®æ¡çšãå¢ããŠããŸãããã®äžã®ãšãã Next.js æ¡çšãããã¯ããäŸãšããŠä»åã玹ä»ããŸãã tsc TypeScript ã§ããNext.js 9 以éã¯ãTypeScript é¢é£ã®æ©èœã¯ãã«ãã€ã³ãããŠã㊠yarn build æã«åæ€æ»ãè¡ããŸããã忀æ»ã ããä»»æã®ã¿ã€ãã³ã°ã§è¡ãå Žåã¯ã tsc -p . --noEmit ã®ãããªã³ãã³ããå®è¡ããŸããLint ããŒã«ã§ã¯ãããŸãããã忀æ»ã®ããã«ã ã䜿çšããŠããã®ã§äžå¿èšèŒããŸããã ESLint ESLint ã§ããNext.js 11 以éã¯ãESLint é¢é£ã®èšå®ããã«ãã€ã³ããããã«ãªãã next lint ã§å®è¡ãšèšå®ãã§ããŸãã Next.js åãã®ã³ã³ãã£ã°ãšããŠã eslint-config-next ããããŸãã以äžã®ã«ãŒã«ã¯ãªãã«ããŠããŸãã "@next/next/no-img-element": "off", "@next/next/no-html-link-for-pages": "off", "@next/next/next-script-for-ga": "off", "@next/next/no-sync-scripts": "off", Next.js ã®æ©èœã掻çšããããã®ã«ãŒã«ããªããªãã«ããŠãããçåã«æããããããããŸããã®ã§çç±ã説æããŸãã no-img-element ã¯ãNext.js ãæäŸãã next/image ã䜿çšããã«ãimg èŠçŽ ã䜿çšããŠããå Žåã«èŠåãè¡ãã«ãŒã«ã§ãããããã¯ãã§ã¯ãSSR ã§ã¯ãªããSSG ã䜿çšããŠã㊠next/image ã¯æªäœ¿çšãªã®ã§ãªãã«ããŠããŸãã no-html-link-for-pages ã¯ãNext.js ãæäŸãã next/link ã䜿çšããã« anchor èŠçŽ ã®ã¿ã䜿ã£ãŠãªã³ã¯ãå®è£
ããŠããå Žåã«èŠåãè¡ãã«ãŒã«ã§ããnext/link ã䜿çšããããšã§ãCSR ã§ããŒãžé·ç§»ãå®çŸããããšãå¯èœã«ãªããŸãããmediba ã§å©çšããŠãã Google Analytics åãã®å®è£
ã§ã¯ããŒãžé·ç§»æã®éèšã«æžå¿µãããããšãåãã£ãŠããŸãããããã£ãçç±ããæå³çã« next/link ã䜿çšããªãããã«ããŠãããããã«ãŒã«ããªãã«ããŠããŸãã next-script-for-ga ãš no-sync-scripts ã¯ã next/script ã®ä»æ§ããã¡ããšèª¿æ»ã§ããŠããªãã£ãã®ã§æ«å®çã« script èŠçŽ ã䜿çšããŠããŸãããä»åŸå¯Ÿå¿ãããããããŸããã Stylelint Stylelint ã§ãããããã¯ãã§ã¯ãstyled-components ã®ãã㪠JS in CSS ã§ã¯ãªãã .scss ãã¡ã€ã«ã«å®çŸ©ãã CSS ã CSS Modules ããå©çšããŠããããããããã£ã®äžŠã³é ã® auto fix çãStylelint ã®æ©èœãå
šãп޻çšããããšãã§ããŠããŸãã ããããã£ã®äžŠã³é å®çŸ©ã¯ã stylelint-config-recess-order ã䜿çšããŠããŸããå®çŸ©ãããŠããããããã£ã®æ°ãšã¡ã³ããã³ã¹ã®é »åºŠã®é¢ã§ãä»ã®ã©ã€ãã©ãªãèªèº«ã§äœæãããããè¯ãããã ã£ãããéžå®ããŸããã ãŸãã Prettier ã䜿çšããŠããã®ã§ stylelint-config-prettier ã§ç«¶åãé²ãã§ããŸãã markuplint markuplint ã§ããHTML Living Standard ã®ä»æ§ã«æºæ ãã HTML ã«ãªã£ãŠããããæ€èšŒã§ããŸããReact (JSX) ã«ã察å¿ããŠããŸãã ã«ãŒã«ãç¬èªã«è¿œå ããŠããŸãã { "nodeRules": [ { "selector": "meta[property]", "rules": { "invalid-attr": { "option": { "attrs": { "property": { "type": "String" }, "content": { "type": "String" } } } } } } ] } meta èŠçŽ ã®å±æ§ã«ã€ããŠã§ããSNS ã§ããŒãžãå
±æãããéã®æåãå®çŸ©ããããããã®ãã㪠meta èŠçŽ ãå®è£
ããããšãå€ããšæããŸãã <meta content="ããŒãžã¿ã€ãã«"> ãã®å®è£
㯠markuplint ã 2 ã€èŠåãåºããŸãããŸããHTML Living Standard ã® meta èŠçŽ ã®ä»æ§ã«ã¯ãproperty 屿§ãå®çŸ©ãããŠããªãããèŠåãåºããŸãã ãŸããname 屿§ãå®çŸ©ãããŠããªãå Žåã«ãcontent 屿§ã䜿çšããããšãã§ããªãããããã¡ãã«ã€ããŠãèŠåãåºããŸãã ã§ã¯äžäœãã®å±æ§ã¯äœãªãã ããšãã話ã«ãªããŸãããproperty 屿§ã«ã€ããŠã¯ RDFa ã§å®çŸ©ãããŠããã OGP ã«åŸã£ãŠãã® meta èŠçŽ ã SNS åŽãè§£éããŸãããããã£ãŠããã§ã¯äŸå€ãšããŠåãæ±ãããã«ã«ãŒã«ã倿ŽããŠããŸãã ãªããReact ç¬èªã®å±æ§ïŒ key ã dangerouslySetInnerHTML ) 㯠@markuplint/react-spec ã«å«ãŸããŠããããç¬èªã«ã«ãŒã«ã远å ããå¿
èŠã¯ãããŸããã䟿å©ã§ãã ãŸãšã çŽè¿ã® Next.js æ¡çšãããã¯ããäŸã«ã䜿çšããŠãã Lint ããŒã«ãšããã®èšå®ã«ã€ããŠã玹ä»ããŸããããããã® Lint ããŒã«ã¯å
šãŠ GitHub Actions ã§ commit push ãããªã¬ãŒã«ããŠå®è¡ããŠããŸãã®ã§ãã«ãŒã«ã«éåããŠããã³ãŒããã³ããããããšããã«æ°ã¥ãããšãã§ããLint ããŒã«éçšã®åœ¢éªžåãé²ãããšãã§ããŠããŸãã Lint ããŒã«ã®å°å
¥ã«ãã£ãŠãã³ãŒãããŒã¹ãã¯ãªãŒã³ã«ä¿ã€ããšã¯ãã¡ããã§ãããæšæºä»æ§ããã¹ããã©ã¯ãã£ã¹ãç¥ãè¯ããã£ããã«ããªã£ãŠããŸãã Lint ããŒã«å°å
¥æã®åèã«ãªãã°å¹žãã§ããæåŸãŸã§ãèªã¿é ãããããšãããããŸããã
ã¯ãããŸããŠãmediba æ°å2å¹Žç® ããŒã¿ã¢ããªã¹ãã®å·Šæµ·ã§ãã mediba Adventã«ã¬ã³ã㌠10æ¥ç®ãšããããšã§ãç§ããã¯GTMã䜿çšããŠèªç€Ÿãµã€ãã«Microsoft Clarity(ããŒããããããŒã«)ãèšå®ãããè©±ãæžããŠãããŸãã Microsoft Clarityã§ã§ããããš Clarityãšã¯ãMicrosoft瀟ãã2020幎10æã«ãªãªãŒã¹ãããç¡æã®ããŒããããããŒã«ã§ãã Clarityã§ã§ããããšã¯ãäž»ã«ä»¥äžã®3ã€ã§ãã ãµã€ã蚪åè
æ°ãé¢è±è
æ°ãä»»æã®ããŒãžã«ãããã¹ã¯ããŒã«ãããå²åãªã©åºæ¬æ°å€ãææ¡ã§ãã 1ãŠãŒã¶ãŒã«ãã©ãŒã«ã¹ããŠããµã€ãäžã§ã©ããªè¡åãããã®ãã»ãã·ã§ã³ã¬ã³ãŒãã£ã³ã°(é²ç»)ã§ãã ã©ããã¯ãªãã¯ããŠãã©ããŸã§ã¹ã¯ããŒã«ããã®ãããŒããããã§èŠèŠçã«å¯èŠåã§ãã å°å
¥ç·š èšå®æé GTMã䜿çšããå Žåã¯ã以äžã®é ã«èšå®ããŠãããŸãã Microsoft Clarity ã¢ã«ãŠã³ããäœæãã GTMã䜿çšããClarity tracking codeãé
ä¿¡ãã GTMã®ãã¬ãã¥ãŒã§ãèšå®ããã¿ã°ãé
ä¿¡ãããŠããã確èªåŸãå
¬éãã Clarityã®ç®¡çç»é¢ã§ãæ£ããæ°å€ãèšæž¬ãããŠããã確èªãã Microsoft Clarityã®ã¢ã«ãŠã³ããäœæãã Microsoft Clarity ã«ã¢ã¯ã»ã¹ããèµ€æ ç®æãã¯ãªãã¯ããŠã¢ã«ãŠã³ããäœæããŸãããã®åŸãå¿
èŠäºé
ãèšå
¥ããŸãã GTMã䜿çšããClarity tracking codeãé
ä¿¡ãã Clarity管çç»é¢ > Settings > SetupããClarity tracking codeãã³ããŒããGTMã®ã¿ã°èšå®ç»é¢ã®HTMLã«è²Œãä»ããŸãã GTMåŽã§ãã¿ã°ã®äœæãšããªã¬ãŒã®èšå®ãè¡ããŸãã ã¿ã°ã®äœæã¯ãGTM 管çç»é¢ > ã¿ã° > æ°èŠ ããäœæãããŸããã¿ã°ãšããªã¬ãŒã®èšå®ã¯ä»¥äžã®éãã§ãã ã¿ã°ã®çš®é¡ïŒã«ã¹ã¿ã HTML ããªã¬ãŒã®èšå®ïŒAll Pages 以äžã§ãã¿ã°ã®äœæãšããªã¬ãŒã®èšå®ã¯å®äºã§ãã GTMã®ãã¬ãã¥ãŒã§ãäœæããã¿ã°ãåé¡ãªãé
ä¿¡ãããŠããã確èªãã GTMã®ãã¬ãã¥ãŒç»é¢ã®Tags Firedã«Microsoft Clarityã¿ã°ã確èªã§ããŸãããåé¡ãªããã¿ã°ãçºç«ãããŠããããã§ããå
¬éãã¿ã³ãã¯ãªãã¯ããŸãã GTMã®èšå®ã¯ä»¥äžã«ãªããŸãã Clarityã®ç®¡çç»é¢ã§ãæ£ããæ°å€ãèšæž¬ãããŠããã確èªãã æåŸã«ãClarityã®ç®¡çç»é¢ã§ãåé¡ãªãæ°å€ãèšæž¬ãããŠããã確èªããŸããã¿ã°å
¬éãã2æéã»ã©ã§ãClarityã®ããã·ã¥ããŒãç»é¢ã«æ°å€ãåæ ãããŸããã ããŒããããã®ããŒã¿ãåæ ãããæŽ»çšã§ããããã«ãªã£ãŠããŸãã GTMçµç±ã§ãèªç€Ÿãµã€ãã«Clarityã®èšå®ãå®äºããŸããã Session Recordingsã«ã€ã㊠以äžã®éããSession RecordingsãæŽ»çšã§ããããã«ãªã£ãŠããŸãããŠãŒã¶ãŒã®ã«ãŒãœã«ã®åããé®®æã«é²èЧã§ããŸãã æŽ»çšæ¹æ³ã®æ€èš Clarityã¯ã©ããã£ãå Žé¢ã§æŽ»çšããããšãã§ããã®ããæ€èšããŸãããããã§ã¯ãä»®èšãšããŠãä»»æã®ããŒãžã®æ¬¡ã®ããŒãžãžã®é·ç§»çãæžå°åŸåã§ãããšããŸãããããããšã以äžã®ãããªèª²é¡çºèŠããæææ±ºå®ãŸã§ã®æµãããèããããŸãã 課é¡çºèŠ ãŸãã¯ã課é¡ãèšå®ããŸããããã§ã¯ãä»®ã®èª²é¡ãšããŠããä»»æã®ããŒãžã®æ¬¡ã®ããŒãžãžã®é·ç§»çãæžå°åŸåã§ããããšããŸãã çŸç¶ææ¡ã»èŠå èª¿æ» GAã®å®éããŒã¿ã䜿çšãã課é¡ã®èŠå ãçªãæ¢ããããšããŸããããããå®éããŒã¿ã ãã§ã¯ãç¹ã«èŠå ãåãããŸããã æ¬¡ã«ãClarityã䜿çšããŠãä»»æã®ããŒãžã§äœãèµ·ãã£ãŠããã®ãã»ãã·ã§ã³ã¬ã³ãŒãã£ã³ã°ãšããŒããããã§èŠå ã調æ»ããŸããäŸãã°é掻æ§ç®æãã¯ãªãã¯ãããŠãããããªå Žåã«ã¯ã誀ã¯ãªãã¯ã§é¢è±ããŠããããšèšãããããããŸããã æ¹ç æ¹çãšããŠä»¥äžã®æ¡ãæµ®ãã¶ã®ã§ã¯ãªãã§ããããã ã¯ãªãã¯ã§ããªãç®æãã¯ãªãã¯ã§ããããã«æŽ»æ§ããã 以äžã®ããã«ãGAã®å®éããŒã¿ã§ã¯æ®æ®µçºèŠã§ããªããããªãŠãŒã¶ãŒã®è¡åã§ãClarityã䜿çšããã°ãç°¡åã«ææ¡ããããšãã§ããã§ãããããã®çµæãæææ±ºå®ã«ã€ãªãããšèããŠããŸãã ãããã« GTMã䜿çšããããšã§ããšã³ãžãã¢ã«äŸé ŒãããšããClarityãèšå®ã§ããã®ã¯äŸ¿å©ããšæããŸãã Clarityã¯ç¡æã§ãã€å®è£
ã«æéãããããŸããããããŠãããŒãããããã»ãã·ã§ã³ã¬ã³ãŒãã£ã³ã°æ©èœãªã©å€æ§ãªæ©èœãé
åçã§ãããã²ãèªèº«ã®ãµã€ãã«Clarityãå°å
¥ããŠã¿ãŠã¯ãããã§ããããã ã©ãªããã®ãåèã«ãªãã°ã幞ãã§ãã
ããã«ã¡ã¯ããšã³ãžãã¢ã®äžçïŒ @yn2011 ïŒã§ããåèçã¯æé«ã§ãã ä»å㯠NewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã° ã䜿çšã㊠JavaScript ã®ãšã©ãŒåéãè¡ãããšããéã«ãNewRelic ã®ãœãŒã¹ãããã¢ããããŒãæ©èœã®ä»æ§ã§è²ã
ãšããã£ãŠããŸã£ããšããã話ãããŸãã ãœãŒã¹ãããã¢ããããŒã API ã«ã€ã㊠NewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã°ã§ã¯ããœãŒã¹ããããšãããã¡ã€ã«ãå©çšããŠçºçãã JavaScript ãšã©ãŒã®ã¹ã¿ãã¯ãã¬ãŒã¹ãååŸããããšãã§ããŸãã ãœãŒã¹ãããã¯ã以äžã®ãããªå
容ã®ãã¡ã€ã«ã§ãã { "version": 3, "file": "static/chunks/254-be419541614271942b8c.js", "mappings": "gFAAoEA,... } NewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã°ã«ã¯ãœãŒã¹ãããã®ããŒãžã§ã³ç®¡çæ©èœãããããœãŒã¹ãããã«ãŠããŒã¯ãªèå¥åãã¢ããããŒãæã«ä»äžããããšãã§ããŸããæäŸãããŠãããœãŒã¹ãããã®ã¢ããããŒã API ãå©çšããŠã¢ããããŒãæã«èå¥åã®ä»äžãã§ããŸãã publishSourcemap({ sourcemapPath: './dist/bundle.js.map', javascriptUrl: 'https://example.com/assets/bundle.js', ... releaseName: 'OPTIONAL RELEASE NAME', // 远å releaseId: 'OPTIONAL RELEASE ID', // 远å }, function (err) { console.log(err || 'Source map upload done')}) releaseName ãš releaseId ãæå®ã§ããããšã«éåæãæã£ãæ¹ããããããããŸãããããã¯æ¬¡é
ã®äŒç·ã§ãã ãããªãã€ã³ã releaseId ãš releaseName ã¯äž¡æ¹å¿
é æ©éäŒç·ãååããŸããNewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã°ã§ããŒãžã§ã³ç®¡çãè¡ãå Žåã¯ã releaseName ãš releaseId ã®äž¡æ¹ãå¿
é ã«ãªããŸãã ããã¥ã¡ã³ãã«èšèŒã¯ãªãããã«èªèããŠããŸããã @newrelic/publish-sourcemap ã®å®è£
ã確èªãããšããã£ããæ¡ä»¶åŒã«å«ãŸããŠããŸããã if (releaseName && releaseId) { console.log('Using release name:', releaseName, 'and release id:', releaseId) request = request.field('releaseName', releaseName) request = request.field('releaseId', releaseId) } ã³ãããããã·ã¥ã掻çšããå Žåãªã©ãã©ã¡ãã 1 ã€ã®é
ç®ãå©çšã§ããã°ååãªããšãå€ããšæããŸãããªããã®ãããªä»æ§ã«ãªã£ãŠããã®ãã¯åãããŸããã§ããã ã³ã³ããªã¯ããšã©ãŒ ãœãŒã¹ãããã®ããŒãžã§ã³ç®¡çãè¡ããªãå Žåã¯ã releaseName ãš releaseId ãæå®ããå¿
èŠã¯ãããŸããããããã1 床ãããã®é
ç®ã空ã§ã¢ããããŒãããŠããŸããšã次ã«ã¢ããããŒãããéã« releaseId ãš releaseName ãæå®ããŠã¢ããããŒãããŠãã³ã³ããªã¯ããšã©ãŒãšããã¬ã¹ãã³ã¹ãè¿ããã¢ããããŒãã倱æããŸãã ã³ã³ããªã¯ããšã©ãŒã¯ãNewRelic ã«åäžã®ãœãŒã¹ããããã¢ããããŒãããå Žåã«çºçãã仿§ãšãªã£ãŠããŸãã releaseName ãš releaseId ãç°ãªãå Žåã¯å¥ã®ãœãŒã¹ããããšããŠè§£éãããããã¢ããããŒããå¯èœã§ãã ããŒãžã§ã³ç®¡çãè¡ãå Žåã¯ã1床ã releaseName ãš releaseId ã空ã®ãœãŒã¹ããããåé€ããå床ã¢ããããŒãããå¿
èŠããããŸãã ãã©ãŠã¶åŽã§ addRelease ãåŒã³åºãå¿
èŠããã ãœãŒã¹ãããã®ããŒãžã§ã³ç®¡çãè¡ãå Žåããã©ãŠã¶åŽã§ browser agent API ããæ¬¡ã®ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã newrelic.addRelease(string $release_name, string $release_id) ãã®ã¡ãœãããåŒã³åºããªããšãçºçãã JavaScript ãšã©ãŒãæ£ããããŒãžã§ã³ã®ãœãŒã¹ãããã«ãããã³ã°ããããšãã§ããŸãããã¡ãœãããåŒã³åºããã« JavaScript ãšã©ãŒãçºçãããå ŽåãNewRelic ã®ç»é¢äžã§ã¯ releaseName ãš releaseId ã¯ç©ºã«ãªããŸãã addRelease ã®åŒã³åºãã®å®è£
ãšããŠã¯ãã¹ããããã®æ«å°Ÿãžã®è¿œå ãå¯èœã§ãã NewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã°ãå©çšããå Žåã¯ãNew Relic ããæäŸãããã¹ããããããã©ãŠã¶ã§å®è¡ããå¿
èŠããããŸãããã®ã¹ããããã®å®è¡åŸã«ãbrowser agent API ãå©çšå¯èœã«ãªãããã以äžã®ããã«æ«å°Ÿã«åŒã³åºãã远å ããŸãã // çç¥... applicationID:"${config.applicationID}",sa:1}; newrelic.addRelease("foo", "bar"); // 远å addRelease ã®åŒã³åºãã¯ãé¡äŒŒãµãŒãã¹ã§ãã Sentry ã§ã¯äžèŠã§ãã£ããããæ€èšŒæã«æ°ã¥ããããã£ãŠããŸããŸããã ãŸãšã NewRelic ãã©ãŠã¶ã¢ãã¿ãªã³ã°ã®ãœãŒã¹ãããã«é¢ããããããã€ã³ãã 3 ã€æžããŸããã æçµçã«ããããã¯ãã§ã¯ãœãŒã¹ãããããŒãžã§ã³ç®¡çæ©èœã®å°å
¥ã¯èŠéããŸããããä»åŸå¿
èŠã«å¿ããŠå¯Ÿå¿ãæ€èšããäºå®ã§ãã æåŸãŸã§ãèªã¿é ãããããšãããããŸããã
ã¯ããã« ããã«ã¡ã¯ãSRE Unitã®å浊( @kitta0108 )ã§ãã åœããã°ã¯ãå·ç掻åãã¢ãã§ãã£ããã©ãããšããæ°ãã詊ã¿ãããŠãããŸããŠã ãã¯ãããžãŒã»ã³ã¿ãŒ6G Managerã®äžå°ãã( @primunu )ã SRE Unitã®æ¿è°·ãã( @mary_tuba )ã ãããŠå浊ã®3人ã§ãéãããŠãããŸãã ããŠãçããã¯ã¢ããªã±ãŒã·ã§ã³ã®å®è¡åºç€ãšããŠã®ã³ã³ããã€ã¡ãŒãžãéžå®ãããšããã©ã®ãããªé¢å¿è»žãæã£ãŠæãã§ãŸããïŒ ä»åã¯Distrolessã€ã¡ãŒãžã«ã€ããŠãäœã®å¬ãã¿ãããã®ããã©ã®ãããªåªäœæ§ãããã®ããªã©ãæ·±æãã£ãŠãããããšæããŸãã çããã®åŒãåºãã®äžã€ãšããŠãç¥èŠã«å ããŠããã ãããããªããšããã£ããªããšãŠãå¬ããæããŸãïŒ å¯Ÿè±¡è
ã€ã¡ãŒãžãéžå®ãã人 = DockerFileãæžã人 ã€ã¡ãŒãžã®è匱æ§å¯Ÿå¿ã匷ããã人 ã³ã³ãããµã€ãºã®è»œéåãè¿œãæ±ããã人 æŠèŠ Distrolessãšã¯ãGoogleãå
¬éããŠããã¢ããªã±ãŒã·ã§ã³ãšãã®ã©ã³ã¿ã€ã äŸåã®ã¿ãå«ãŸããDebian10(buster)ã«åºã¥ããŠäœæãããã³ã³ããã€ã¡ãŒãžã§ãã https://github.com/GoogleContainerTools/distroless å¿
èŠãªäŸåã®ã¿ãå«ãŸãããšã¯ïŒ Distrolessã«ã¯ã¢ããªã±ãŒã·ã§ã³ã®å®è¡ã«å¿
èŠãªäŸåããå«ãŸããŠããŸããã ãªã®ã§ãShellã¯ããããaptãcdãšãã£ãæ©èœãæããŠããŸããã ã ãããããè¯ããããã§è¯ãã®ã§ãã以äžãã芧ãã ããã ãã®å³ã¯AWSã®ECRã«ãããã以äžã®ãã¬ãŒã³ã€ã¡ãŒãžãããã·ã¥ããçµæã«ãªããŸãã ïŒGoã®ã¢ããªã±ãŒã·ã§ã³ãåãããšããåæã§ã€ã¡ãŒãžãéžãã§ãŸããïŒ alpine:3.13 golang:1.16.5-buster gcr.io/distroless/static-debian10 ã©ãã§ããããããã®æç¹ã§å¬ãã¿ãã€ã³ãã2ã€èŠããŠããŸãããïŒ å¬ãã¿ãã€ã³ããã®1 軜éã§ãããšããããš Debianã®318MBãšããã®ã¯çœ®ããŠãããŠw Alpineã®2.81MBãšæ¯èŒããŠãDistrolessã®0.66MBã¯ãã¡ããã¡ã軜ãã§ãã ã³ã³ãããæ±ãäžã§ã¯ãã€ã³ãã©ã®æ¯ãèããšããŠãã¹ã±ãŒãªã³ã°æ§èœã坿¬æ§ã®åäžãæåŸ
ãããã§ãããããã®è»œéãã€ã³ãã¯å¬ããã§ãããã å¬ãã¿ãã€ã³ããã®2 ã»ãã¥ã¢ã§ãããšããããš å®ã¯ãã£ãããšECRã«Image Scanningæ©èœãONã«ããŠãããŸããã ããã§ãDistrolessã€ã¡ãŒãžã¯å ã
ã®Noneã®æåã…ïŒ ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããäžã§äœåãªäŸåãå«ãŸããªããšããããšã¯ãããã ãè匱æ§ãé²åããå¯èœæ§ãäœããªãããšã«ãç¹ãããŸãã ã³ã³ããã€ã¡ãŒãžã®ã¬ã€ã€ãŒã§ãããæããããã®ã¯å¬ãããã€ã³ãã§ãããã ã€ã¡ãŒãžã®ããŒãžã§ã³äžãäœæ¥ã®é »åºŠãå°ãªããªãããã§ãã ãŸãšã ä»åã¯ã¢ããªã±ãŒã·ã§ã³ã³ã³ããã®ã€ã¡ãŒãžãšããŠDistrolessã玹ä»ããŠã¿ãŸããããããã§ããã§ããããã å©çšããŠããèšèªãDistrolessã«å¯Ÿå¿ããŠããã®ã§ããã°ãç©æ¥µçã«å©çšãæ€èšããŠããããšå人çã«ã¯æããŸãã ãã ããDistrolessãå©çšããã€ã¡ãŒãžã®äœæã«ã¯Shellãå«ãŸããŠããªããšããç¹ã§ã¡ãã£ãšããã³ããå¿
èŠã«ãªããŸãã æéããã£ãããã€ã¡ãŒãžã®äœææ¹æ³ãªã©ãå
·äœçã«ãããã®ãæžããŠã¿ããã㪅ïŒïŒ
ã¯ãããŸããŠã2021幎床æ°åã®æšæã§ãã ããã³ããšã³ããšã³ãžãã¢ãšã㊠ãã¯ãããžãŒã»ã³ã¿ãŒ5G ã«æå±ããŠããŸãã ä»åã¯ãNuxt.js ãªãã³ã« TypeScript ãå©çšããŠãç°¡åãªæœéžããŒã«ãäœæããŠã¿ãå
容ã«ã€ããŠã玹ä»ããŸãã Nuxt.js ãš TypeScript Nuxt.js ã¯ãVue.js ããŒã¹ã® JavaScript ã®ãã¬ãŒã ã¯ãŒã¯ã§ããWebããŒãžæ§ç¯ã«æçšãª UI 以å€ã®æ©èœïŒ Ajax ããµãŒããŒãµã€ãã¬ã³ããªã³ã°ãªã©ïŒããŸãšããŠå©çšã§ããç°å¢ãæäŸããŠãããŸãã Nuxt.js å
¬åŒãµã€ã TypeScript ã¯ãçç¥å¯èœãªéçåä»ããšã¯ã©ã¹ããŒã¹ãªããžã§ã¯ãæåãå ãã JavaScript ã®ã¹ãŒããŒã»ããïŒäžäœäºæïŒã§ããäžèšã§èšããšãåå®çŸ©ã§ãã JavaScript ãã TypeScript å
¬åŒãµã€ã ãªãæœéžããŒã«ãäœã£ãã®ã äž»ãªçç±ã¯ã以äžã®2ç¹ã§ãã ç§ã®æå±ããããŒã ã§æ±ã£ãŠãã Nuxt.js ããã³ Typescript ã®æŠèŠãæŽããã ããŒã å
ã§MTGã®ãã¡ã·ãªããŒã¿ãåã£ãŠããŸã課é¡ã解決ãããã å®æç© ãã£ããã§ããã宿ããç©ããã¡ãã ã©ã³ãã ã«ãŠãŒã¶ãŒãæœéžã§ããã·ã³ãã«ãªããŒã«ã§ãã ãã¶ã€ã³ã¯è¿å¹Žæµè¡ã£ããã¥ãŒã¢ãŒãã£ãºã ãåãå
¥ããŠã¿ãŸããã å°ãªãé
è²ã§ãå¹åžã«ãã£ãŠå¥¥è¡ããã§ããã®ã§ãã·ã³ãã«ãªããŒã«ã§ãèŠæ ããè¯ããªããŸãã 䜿ã£ãæè¡ Nuxt.js 2.15.7 TypeScript 4.2.4 Vue.js 2.6.14 Vuex 3.6.2 firebase 8.7.1 tailwindcss 2.2.4 sass 1.35.1 ç°å¢ M1 Mac VSCode yarn æ©èœ ä»åã®æœéžããŒã«ã®æ©èœã¯ä»¥äžãšããã§ãã ãŠãŒã¶ãŒãç»é²ã»åé€ãã ãŠãŒã¶ãŒæ
å ±ãDBã§ä¿æãã ç»é²ãããŠãŒã¶ãŒããã©ã³ãã ã«æœéžãã å®äºãã人ã»äŒã¿ã®äººã«ãã§ãã¯ããæœéžå¯Ÿè±¡ããå€ã æœéžçµäºåŸãéžã°ãã人ã¯èªåã§å®äºãã§ãã¯ããã å
šå¡ãã§ãã¯ãããäžæ¬ãªã»ããã§ãã äœææé å
šäœçãªæµãã¯ä»¥äžã®ãšããã§ãã ç°å¢æ§ç¯ åæ©èœäœæ Vuexå°å
¥ firebaseå°å
¥ 1. ç°å¢æ§ç¯ create-nuxt-appãå©çšããŠç°å¢ãæ§ç¯ããŸããã create-nuxt-app å
¬åŒãµã€ã ãš Nuxt.js å
¥éã®èšäº ãåèã«ããŸããã 2. åæ©èœäœæ åè¿°ããåçš®æ©èœãå®è£
ããŠãããŸãã æ¬ åžè
ã®å¯Ÿå¿ å®äºãã人ã ãã§ãªããäŒã¿ã®äººãªã©æœéžå¯Ÿè±¡ããé€å€ãããå Žåãæ³å®ããŠãå®äºãã§ãã¯ãšã¯å¥ã«é€å€ããããŠãŒã¶ãŒãæå®ã§ãããããã©ã°ãæãããŠããŸãã ã³ã³ããŒãã³ãã«ã€ã㊠å人çã«èŠåŽããã®ã¯ã³ã³ããŒãã³ãåšãã§ãã ãŸããã©ã®ãããã®åäœã§åºåãã°è¯ãã®ãããããªãŸããã§ããã ããã§ä»å㯠Atomic Design ãåèã«åãåºããŸããã ãŸããä»ã®ç®æã§ã䜿ããããã«æ±çšçã«äœãããšã§ãã ã¯ãªãã¯ãªã©ã®ã€ãã³ãã¯å
šãŠèŠªãžæž¡ããã¹ã¿ã€ã«ã衚瀺ã®å€æŽã¯èŠªããå€ãæž¡ãããã«ããããšã§ãatomsåäœã®ã³ã³ããŒãã³ããã©ãã§ã䜿ããããå¿ãããŸããã äŸãã°ãã¿ã³ã³ã³ããŒãã³ãã¯ãäºãããã€ãã®ã¹ã¿ã€ã«ãå®çŸ©ããŠããã芪ã³ã³ããŒãã³ãã§äœ¿ããšãã«äžèšã®ããã« props ã§å¿
èŠãªã¹ã¿ã€ã«ãæž¡ããšãšãã«ã$emit ã§ã¯ãªãã¯ã€ãã³ããèŠªã«æž¡ããŠããŸãã //Button.vue <div> <button :class="[ colorStyle[buttonColor], sizeStyle[buttonSize], fontStyle[buttonFont], ]" @click="$emit('button-click')" > <slot></slot> </button> </div> //Input.vue <Button button-color="gray" button-size="short" button-font="small"> ADD </Button> ãããŠã³ã³ããŒãã³ãéã®ããŒã¿ã®åãæž¡ãã§ãã äŸãã°ãŠãŒã¶ãŒæ
å ±ã¯ãåãã emit ã§èŠªã³ã³ããŒãã³ãã«å€ãåŒãæž¡ããããã«å¥ã®åã³ã³ããŒãã³ãã« props ã§æž¡ããŠè¡šç€ºããŠããŸãã ä»åã¯ã·ã³ãã«ãªããŒã«ãªã®ã§ã³ã³ããŒãã³ããå°ãªãã§ãããããããåãæž¡ããéãªã£ãŠãããšã³ãŒããç
©éã«ãªãã¡ã³ããã³ã¹ããã¥ãããªããŸããããã§ãVuex ãå°å
¥ãç¶æ
管çãããããšã«ããŸããã 3. Vuex å°å
¥ Vuex ã®ã¹ãã¢ã§ãŠãŒã¶ãŒæ
å ±ã®ç¶æ
ã管çããŸãã ä»åã¯DBã䜿ãäºå®ãªã®ã§ãactions ã§DBã«æ¥ç¶ããåŸãå€ã state ã«åæ ãããŠããŸãã Nuxt.js 㯠store ãã£ã¬ã¯ããªã«ãã¡ã€ã«ãäœæããã ãã§ã¹ãã¢ãæå¹åããŠãããã®ã§äŸ¿å©ã§ãããä»åã¯ç®¡çããã®ããŠãŒã¶ãŒæ
å ±ã ããªã®ã§ãindex.ts ãäœãã users.ts ãçŽäžã«äœããŸããã Vuex ã¹ãã¢ã§ããŒã¿ãäžå
管çã§ããã®ã§ãæ¬åœã«ãããããããªããŸãããã³ã³ããŒãã³ããè¶
ããŠå
±æãããæ
å ±ã管çããã«ã¯ããšãŠã匷åãªããŒã«ã ãšæããŸãã äžæ¹ã§ãVuex ã䜿çšããéã«ã¯ã泚æç¹ããããŸãã äŸãã°ãå°ããã¬ãã«ã®ã³ã³ããŒãã³ããã㯠Vuex ã䜿çšããªãæ¹ãè¯ãã§ãããã ã³ã³ããŒãã³ãã®äœ¿ãåããé£ãããªãã®ãšãïŒç»é¢ã®äžã§è€æ°ã®ç®æãã Vuex ã®ã¹ãã¢ãžã®åç
§ãšå€æŽãå
¥ãçµãã å ŽåãåŠçã远ãã«ãããªãããã§ãã åèïŒ Vuexã¯ãªãã¹ãé¿ãã ããã Vuexã§äœãããããäœãããªãã Vuex ãå©çšããéã¯ã Atom ã Molecule ã¬ãã«ã®ã³ã³ããŒãã³ãã®äžã§ã¯äœ¿ããªã ã state ãçŽæ¥åç
§ããªã ããªã©ã®ã«ãŒã«ãèšããŠéçšããããšæããŸãã 4. firebase å°å
¥ DBãšãããã€ã¯ firebase ãå©çšããŸãã firebase ã¯ä»¥åã«ã䜿ã£ãããšããããŸãããããã¯ã firestore ã䜿ãã°é¢åãªæéããããã«DBãå®è£
ã§ããŸãããäžæ³ã ãããã€ã firebase ã® Hosting ã䜿ã£ãŠè¡ããŸããã ããã«ãä»åã¯ç€Ÿå
åãããŒã«ãªã®ã§ããããã€ã«ãããå€éšããã®ã¢ã¯ã»ã¹ãå¶éããããã Authentication ã䜿çšããŠãã°ã€ã³èªèšŒã远å ããŸãã管çè
ã¢ã«ãŠã³ããšããŠãŠãŒã¶ãŒãäžäººã ãç»é²ããç°¡åãªPWãæãŠã°èª°ã§ã䜿ããããã«ããŸããã ãã°ã€ã³ããŠããªãç¶æ
ã§ã¯èªèšŒåŸã®ããŒãžãžé£ã¹ãªãããã«ããããã匷å¶çã«indexãžãªãã€ã¬ã¯ãããmiddlewareã远å ããŠããŸãã const auth = firebase.auth() const middleware: Middleware = ({ route, redirect }) => { auth.onAuthStateChanged((user) => { if (!user && route.name !== 'index') redirect('/') }) } ãŸããAuthentication ã®èªèšŒç¶æ
ã¯ãããã©ã«ãã§ã¯ãŠãŒã¶ãŒããã©ãŠã¶ãéããåŸã§ãæ°žç¶çã«ç¶æãããããã«ãªã£ãŠããŸãã ä»åã¯ç®¡çè
ã¢ã«ãŠã³ãäžã€ã ãã®äœ¿çšã«ãªãããããã°ã¢ãŠãããã«ãŠã£ã³ããŠãéããŠããŸããšãä»ã®äººãã¢ã¯ã»ã¹ããæã§ãåã®ã»ãã·ã§ã³ãç¶ãããšã«ãªããŸãã ããã§ã firebase.auth().setPersistence ã¡ãœããã§æ°žç¶æ§ã¿ã€ãã SESSION ã«å€æŽããããšã§ããŠã£ã³ããŠãã¿ããéãããã³ã«ãã°ã€ã³ç¶æ
ãã¯ãªã¢ãããããã«ããŸããã ã¡ãªã¿ã«ãNuxt.js ã«ã¯ nuxt/firebase ãšããã¢ãžã¥ãŒã«ããããŸããfirebase ãããç°¡åã«å©çšã§ããã®ã§ãèå³ãããã°ã芧ãã ããã è©°ãŸã£ããšãã sass ã®å°å
¥ sass ã®å°å
¥ã§æ²ŒããŸãããã©ããã node ã®ããŒãžã§ã³16 ã〠M1ããã ã ãš node-sass ãåããªãããã§ãïŒ2021/09 å·çæç¹ïŒãnode ã®ããŒãžã§ã³ãäžããããšã§è§£æ±ºããŸããã åå®çŸ© Vuex ã§ã®åå®çŸ©ãprops ã§ã®åå®çŸ©ãfirebase ã§æ±ãæ¥æã®åå®çŸ©âŠ åæšè«ãå¹ãããæ°ã¥ãã°anyã«ãªã£ãŠããåã«èŠãããããŸããã ç¹ã« Vuex ã¯ãã¹ãã¢ãžã¢ã¯ã»ã¹ããããã®äŸ¿å©ãªåããªããä»å䜿çšãã this.$store 㯠Nuxt.js ã§åæå®ãããŠããŸããã èªåã®åã䜿ããã nuxt-typed-vuex ãå©çšããããšã§æ¹åãããããªãããã§ãã ãŸãã TypeScript ãš Vuex ã®çžæ§ã¯è¯ããªããã³ã³ããŒãã³ããã store ãåŒã³åºãããšãã«åå®å
šãå®ãããªããã€ã³ããªã»ã³ã¹ãå¹ããªããšãã£ãåé¡ããããŸãã æ¬¡ã« TypeScript ã§ Vuex ãæ±ãéã¯ãNuxt.js å
¬åŒã§æšå¥šãããŠãã vuex-module-decorators ã䜿çšããããšæããŸãã æ¯ãè¿ã ããŠããããŸã§é·ã
ãšæžããŠããŸããããä»åã®ã¢ãŠãããããéã㊠Nuxt.js ãš TypeScript ã®æŠèŠã¯å€§äœæŽããããªããšããæãã§ãã çµè«ãNuxt.js 䟿å©ïŒ æ¥æ¬èªããã¥ã¡ã³ããå
å®ããŠããŠã»ãŒèª°ã§ãç°¡åã«å§ããããšãã§ãã ã«ãŒãã£ã³ã°ãèªåã§äœæããå¿
èŠããªã SSRãªã©ã¢ãŒããéžã¹ããŠæè»ãªãµã€ãèšèšãã§ãã âŠãªã©ãNuxt.js ã䜿ãããšã§çŽæçã«DOMã®å
容ãæäœã§ããããç°¡åã«æœéžããŒã«ãäœãããšãã§ããŸããã ãŸããTypeScript ã«ã€ããŠããåå®çŸ©ã®ãããã§ãã³ã³ããŒãã³ãéã®ããŒã¿ã®åãæž¡ãã§ãã©ãããåã倿ã§ããã³ãŒããèŠããããªããŸãã ããã«ãåè£å®ã®ãããã§ã³ãŒããæžãæéãççž®ã§ããããšã©ãŒãã§ãã¯ãæ©æ¢°ã«ä»»ããããšãã§ããããªã©å€ãã®ã¡ãªããããããŸããã äžæ¹ã§ãVuexãšã®é£æºã¯å
¬åŒã§æšå¥šãããŠããããã±ãŒãžã䜿ããªã©ãæ¹åã®äœå°ããããŸãã æåŸã« 以äžãNuxt.js ãå©çšããŠæœéžããŒã«ãäœæããŠã¿ãå
容ã®ç޹ä»ã§ããã æåŸãŸã§èªãã§ããã ããããããšãããããŸããã ã©ãªããã®åèã«ãªãã°å¹žãã§ãã
ããã«ã¡ã¯ããšã³ãžãã¢ã®äžçïŒ @yn2011 ïŒã§ãã8 æããåèçæ°ã«ãªããŸãã å
æ¥ãæ°ããŒã çºè¶³ã«ããããããŒã ãã«ãã£ã³ã°ã®ã¯ãŒã¯ã·ã§ãããšããŠæåãªã€ã³ã»ãã·ã§ã³ãããã®äœæã«ãã£ã¬ã³ãžããŸããããã®éã«æ¹ããŠã€ã³ã»ãã·ã§ã³ãããã«ã€ããŠå匷ãçŽããã®ã§ããã å®éã«ããŒã ãã©ããã£ãçµç·¯ã§ãã©ã®ããã«ã€ã³ã»ãã·ã§ã³ããããäœæããã ããšããå
·äœçãªäºäŸã®å
¬éãå°ãªããªãšæããŸããã ããã§ä»åã¯ãç§éã â ãªãã€ã³ã»ãã·ã§ã³ããããäœæããâ¡ ã©ã®ããã«ã¯ãŒã¯ã·ã§ãããé²ããã®ãã⢠ãããŠäœãåŸãããã®ã ã«ã€ããŠæžããããšæããŸãã ãªãã€ã³ã»ãã·ã§ã³ããããäœæããã æ°ããŒã çºè¶³ æ°ãããã¯ãã®éçºã決ãŸããããžãã¹ããŒã ãå
è¡ããŠäŒç»ãšèŠæ±ã®æŽãåºããè¡ã£ãŠããŸãããããçšåºŠã®æŽçãå®äºããããããã¶ã€ããŒãšãšã³ãžãã¢ãåæµããæ¬æ Œçã«éçºãå§ããŠãããããšããçµç·¯ã§æ°ããããŒã ã圢æãããŸããã ãããã£ãŠãããã§èšããããŒã ããšã¯ãç¹å®ã®è·çš®ã®ã¿ã§æ§æãããããŒã ã§ã¯ãªããããžãã¹ã®ã¡ã³ããŒããã¶ã€ããŒçãããã¯ãéçºã«å¿
èŠãªå
šãŠã®è·çš®ãå«ãããŒã ã§ãã ã¡ãªã¿ã«ããšã³ãžãã¢å士ãããžãã¹ã®ã¡ã³ããŒå士ã¯ãããŸã§ãåãããŒã ã§ä»äºãããŠããŸãããããšã³ãžãã¢ãšããžãã¹ã®ã¡ã³ããŒå士ã¯ã»ãŒäžç·ã«ä»äºãããããšããããŸããã§ããã äœã課é¡ã ã£ãã ãã¶ã€ããŒãšãšã³ãžãã¢ã¯éäžããããžãã¹ããŒã ã«åæµãããããªã®ã§ãããããéçºãããããã¯ãã®ç®çããããžã§ã¯ããšããŠäœãéèŠèŠããŠããã®ãçããã£ããçè§£ã§ããŠããŸããã§ããããããã£ãŠã ãããã¯ãã®èŠæ±äºé
ãæžãããããã¥ã¡ã³ããèªãã§ãããããé©åãªã®ãããªãå¿
èŠãªã®ããšããéšåã®çè§£ãçŽåŸåºŠãäœã ç¶æ
ã§ããã ãŸãããããã¯ãã®éçºãå§ããããã«ã¯ãèŠæ±ãèŠä»¶ã«èœãšã蟌ãã äžã§ååã«ãªãªãŒã¹ãããç¯å²(MVP) ãæ±ºããå¿
èŠããããŸããã ã©ãããã ãã® 2 ã€ã®èª²é¡ã«ã€ããŠãããŒã ã¡ã³ããŒãšçžè«ããã€ã³ã»ãã·ã§ã³ããããäœæããããšãšããŠãŒã¶ãŒã¹ããŒãªãŒãããã³ã°ãè¡ãããšã§èª²é¡ã解決ããããšã«ãªããŸãããïŒãªãããã®èšäºã§ã¯ã€ã³ã»ãã·ã§ã³ãããã«ã€ããŠã®ã¿åãæ±ããŸãïŒ ããããããããšããã®ã¯ç°¡åã§ãããå®éã«ç§ãã€ã³ã»ãã·ã§ã³ãããäœæã®ã¯ãŒã¯ã·ã§ãããäŒç»ããã«ããããããã€ãã®èª²é¡ã«çŽé¢ããããšãšãªããŸããããšãŠãçŸå Žææº¢ãããã®ã§ãã äŸãã°æéã®é¢ã§ã¯ä»¥äžã®èª²é¡ããããŸããã åå ããŠæ¬²ããé¢ä¿è
㯠15 人以äžã§ãå
šå¡ãåå å¯èœãªæ¥çšã®èª¿æŽãé£ãã æ¢ã«å€ãã®äºå®ãçµãŸããŠããŠã1 æé以äžã®æéã®ç¢ºä¿ãé£ãã ãããã¯ãã®ãªãªãŒã¹æ¥ã¯å€§ãŸãã«æ±ºãŸã£ãŠããããšãããã§ããã ãæ©ãå®äºãããªããã°ãããªã ãããã®å¶çŽãããã€ã³ã»ãã·ã§ã³ããã㯠10 åã®é
ç®ã§æ§æãããŠããŸãããéèŠã ãšæãããã€ãã®é
ç®ãéžæãããã以å€ã®é
ç®ã¯æ€èšå¯Ÿè±¡ããå€ããŸããããããŠãã¯ãŒã¯ã·ã§ãã㯠1 å 1 æéã§ãè€æ°åã«åå²ããããšãšããŠãäœãšãå
šå¡åå ã®ã¯ãŒã¯ã·ã§ãã宿œã®èŠéããç«ãŠãããšãã§ããŸãããã¡ãªã¿ã«ãåå å¯èœãªã¡ã³ããŒã ãã§å®æœããŠåŸã§çµæãå
±æããããšãã£ãããæ¹ã¯ããæ¥µåå
šå¡åå ã«æããŸãããã€ã³ã»ãã·ã§ã³ãããã¯çµæãšåããããæ§ç¯éçšã®è°è«ã倧äºã ãšèããŠããããã§ãã ãŸããå
容ã®é¢ã§ã¯ä»¥äžã®èª²é¡ããããŸããã ã€ã³ã»ãã·ã§ã³ãããã®ã¯ãŒã¯ã·ã§ãããå®éã«ãã¡ã·ãªããŒãããçµéšã®ããã¡ã³ããŒãããªã ããããã€ã³ã»ãã·ã§ã³ããããç¥ããªãã¡ã³ããŒãå€ã ãããã«ã€ããŠã¯ãç§ãæžç±ã Web ããæ
å ±ãåŸã€ã€åµæå·¥å€«ããŠå®æœããŠããããšã«ãªããŸããã ã©ã®ããã«ã€ã³ã»ãã·ã§ã³ããããäœæããã æ€èšã®çµæãã¯ãŒã¯ã·ã§ããã®ã¢ãžã§ã³ãã¯ä»¥äžã«ãªããŸãããããªãå³éžããæäœéå¿
èŠã ãšæã 3 ã€ã®é
ç®ã®ã¿ãéžã³ãŸããã èªå·±çŽ¹ä» ã€ã³ã»ãã·ã§ã³ãããã®èª¬æ æã
ã¯ãªãããã«ããã®ã ãšã¬ããŒã¿ãŒããã ãã¬ãŒããªãã¹ã©ã€ã㌠åå²ããŠã¯ãŒã¯ã·ã§ãããè¡ãããšã«ããŠããã®ã§ãååã¯ãæã
ã¯ãªãããã«ããã®ãããŸã§ã§ã次åã«æ®ãã®ã¢ãžã§ã³ããæ¶åããŸããã ã§ã¯ãããããã©ã®ããã«é²ããŠãã£ãã®ããåœæ¥ã®æ§åãšåãããŠãäŒãããŠãããŸããïŒãèªå·±ç޹ä»ãããã€ã³ã»ãã·ã§ã³ãããã®èª¬æãã«ã€ããŠã¯äžè¬çãªãã®ãªã®ã§çç¥ããŸãïŒ ãªããä»ç®ã䜿ãããããšãšãåååšå®
å€åã®ãã Miro ã䜿çšããŠãªã³ã©ã€ã³ã§å®æœããŸããã æã
ã¯ãªãããã«ããã®ã ãæã
ã¯ãªãããã«ããã®ããã¯ããããžã§ã¯ãã®ç®çã«ã€ããŠèªèãåãããããã®ã¯ãŒã¯ã·ã§ããã§ãã æåã«å人ã¯ãŒã¯ã®æéãåã£ãŠã1 人ãã€èªåã®èããä»ç®ã«æžããŠããããŸããããã®åŸã«å
±æã®æéãåãããã¡ã·ãªããŒã¿ãŒãè£è¶³ã質åãšã䌌ãŠããæèŠã®ã°ã«ãŒãã³ã°ãããŠãããŸããã ãã¡ããå®éã®ã¯ãŒã¯ã·ã§ããã®çµæã§ãã ã°ã«ãŒãã³ã°ã¯é£ããã§ããã倧ããã¯å®æ§çãªãã®ãšå®éçãªãã®ã§ 2 ã€ã«åããŸãããäžã®å³ã§ã¯ 3 ã€ã«åãããŠããŸããã宿§ã®ãã®ãæŽã« 2 ã€ã«åå²ããŠããŸãã äŸãã°ã宿§çãªç®çã¯ããŠãŒã¶ã«ããšãã䟡å€ãæäŸãããçã§ãå®éçãªç®çã¯ãå©çšç x % åäžãçã§ãã åºæ¬çã«ã©ã®æèŠãééã£ãŠãããšããããšã¯ãªãã®ã§ãããã©ãããŠã宿§çãªãã®ã»ã©éæã§ãããã©ããã倿ãã«ããè§£éã«ããã¬ããããŸããå®éçã§ã éæã§ããªããã°ãããžã§ã¯ããè§£æ£ã«ãªããã®ã¯ã©ãã ãšåãçŽãããšã§ãæç¢ºãªç®çãæ¢ããŠãããŸãããããã¯åæãšãªã£ãŠããã€ã³ãããã®å·®ãããã®ã§ãããžãã¹ããŒã ã®æ¹ã
ã«ãªãŒãããŠæ±ºããŠé ããŸããããã ããä»åã¯ãã®æç¹ã§ã¯å
·äœçãªæ°å€ãŸã§ã¯çã蟌ããŸããã§ãããã²ãšãŸãã¯ãããžã§ã¯ããåãã£ãŠããæ¹åã®èªèãåãããããšã倧äºãªã®ã§ãèšæž¬å¯èœãªææšã§ãããªãã°è¯ãã®ããªãšæããŸãã ãšã¬ããŒã¿ãŒããã ãšã¬ããŒã¿ãŒãããã¯ãäºåã«çšæããããã³ãã¬ãŒããåããããšã§ããããã¯ãã®éªšæ Œãæããã«ããã¯ãŒã¯ã·ã§ããã§ãã ã¡ãªã¿ã«ãéåžž ãšã¬ããŒã¿ãŒããã㯠1 ãããã¯ãã«å¯ŸããŠäœæããŸãããä»åã¯é¢é£ãããããã¯ããè€æ°ååšããŠããã®ã§åãæéã«è€æ°ã®ãšã¬ããŒã¿ãŒããããäœæããŸãããè€æ°ãããã¯ããåæã«éçºããå¿
èŠããã£ãã®ã§ãïŒçŸå®ã¯æç§æžéãã«ã¯ãããªããšããããšã宿ã§ããŸãïŒ ãšã¬ããŒã¿ãŒãããã®é²ãæ¹ãšããŠã¯ããã³ãã¬ãŒãã®é
ç®ã 1 ã€ãã€åããŠããæ¹æ³ãåããŸããã1 ã€ã®é
ç®æ¯ã«ãå人ã¯ãŒã¯ â å
±æ â ã°ã«ãŒãã³ã° â æçµçãªçããšããæé ãèžã¿ãŸãããïŒåãã¯ãäžæ°ã«å
šãŠã®é
ç®ãåããŠããã 1 人ãã€å
±æããŠããã£ãã®ã§ãããä»ç®ã®æŽçããã«ããã®ãšãæåã®é
ç®ã®èªèãåã£ãŠããªããšåŸåã®å
容ãç°ãªã£ãŠããã®ã§ããæ¹ãå€ããŸããïŒ ãã¡ããå®éã®ã¯ãŒã¯ã·ã§ããã®çµæã§ããå³ã®ä»ç®ãå人ã¯ãŒã¯ã§æžããŠé ãããã®ã§ãå·Šã®èµ€ãä»ç®ãæŽçããçµæã§ãã ãšã¬ããŒã¿ãŒãããã§æèŠãåãããããã£ãã®ã¯ããŠãŒã¶ã¯èª°ãªã®ãããšãå·®å¥åèŠçŽ ã¯äœãªã®ããã§ãããå®çŸ©ãé£ãããããªã®ãã çµéšäžãã®éšåãææ§ãªãŸãŸãããã¯ãã®éçºãé²è¡ããããšãå€ãã®ã§æåã«ç¢ºèªã§ãã ã®ã¯ãã®ã¯ãŒã¯ã·ã§ããã®å©ç¹ã ãšæããŸããã ãã¬ãŒããªãã¹ã©ã€ã㌠ãã¬ãŒããªãã¹ã©ã€ããŒã¯ãããžã§ã¯ãïŒãããã¯ãïŒã§äœã倧åã«ãããã®åªå
é äœã決ããã¯ãŒã¯ã·ã§ããã§ãã ä»åã¯ãããã¯ããšããããã¯ååã®ãªãªãŒã¹ãŸã§ã«æéãåºåã£ããããžã§ã¯ããšããŠã®åªå
é äœãšããŠæ€èšããŸããã ãã£ããæ©ã¿ãŸããããé²ãæ¹ã¯ä»¥äžã«ããŸãããïŒä»ç®ããããã·ãŒã«ãšããŠå©çšããã€ã¡ãŒãžã§ãïŒ å人ã§ã¯ãªãè·çš®ããšã«è²åãããä»ç®ãå©çšããïŒãšã³ãžãã¢ãªãé»è²çïŒ å人æ¯ã«èªåã®è·çš®ã«è©²åœããä»ç®ãå©çšããŠã1 çªåªå
é äœãé«ããšæããã®ã«æç¥š 次㫠1 çªåªå
é äœãäœããšæããã®ã«æç¥š æç¥šçµæãå
ã«ãããžã§ã¯ããšããŠã®åæã圢æãã ãã¡ããå®éã®ã¯ãŒã¯ã·ã§ããã®çµæã§ããä»åã¯éœåã«ããäºç®ã¯æ€èšããå€ããŸããïŒäºç®ã®å¢æžãå®è³ªçã«äžå¯ïŒ ã¹ã©ã€ããŒã®åé
ç®ã¯ãã¹ã³ãŒããæéãå質çã®èšèã䜿ãããŸãããå¿
èŠã«å¿ããŠèšãæããè¡ãããšã«ãã£ãŠåå è
ã®èªèéœéœ¬ãé²ãã§ããŸãã åå¥ã®èŠçŽ ã®è©äŸ¡å€ã 2 ãªã®ã 3 ãªã®ããšãã£ãéšåã¯ããŸãè°è«ãããéèŠãªãã®ã«ã€ããŠãã£ãããšèªèãåãããŸãããåªå
é äœãäžéã®ãã®ã«ã€ããŠã¯ãæ£çŽããŸããããžã§ã¯ãã®é²è¡äžã«æèãããããšã¯å°ãªããšæã£ãããã§ãããŸããå人æ¯ã§ã¯ãªããè·ç𮿝ã«ããã®ã¯åå 人æ°ãå€ãããã§ããè·ç𮿝ã®åŸåã倧ãŸãã«ææ¡ããæ¹ãå¹çè¯ãè°è«ã§ãããšèããŸããã ãã¬ãŒããªãã¹ã©ã€ããŒã«ãã£ãŠã ãªãªãŒã¹ã®ææ¥ã«å¯Ÿããã¹ããŒã¯ãã«ããŒã®æž©åºŠæçããããžã§ã¯ãã®å¶çŽã«ã€ããŠå
šå¡ã®èªèãæããããšãã§ãã ã®ã¯å©ç¹ã ãšæããŸããããŸãããããžã§ã¯ãäžç€ã§ã®æ©èœè¿œå ãæ¹é倿Žã«å¯ŸããŠããã¬ãŒããªãã¹ã©ã€ããŒã®åªå
é äœã«åŸã£ãŠæææ±ºå®ãè°è«ãè¡ããç¹ãé
åçã§ãã ã€ã³ã»ãã·ã§ã³ãããããã£ãŠã¿ãŠã©ãã ã£ãã ã€ã³ã»ãã·ã§ã³ãããã®ã¯ãŒã¯ã·ã§ããã®çµäºåŸã«ãåå è
ã®æ¹ã
ããææ³ãé ããŸããã ã€ã³ã»ãã·ã§ã³ãããã®äœæãã©ããã£ããã®ãç¥ãããšãã§ãã ã¯ãŒã¯ã·ã§ãã圢åŒã§è°è«ãã§ããããšã«ãã£ãŠããããã¯ãã«ã€ããŠçè§£ãæ·±ãŸã£ããèªèéœéœ¬ãããããšã«æ°ã¥ãã ãšãã£ãããžãã£ããªææ³ãé ããŸãããã€ã³ã»ãã·ã§ã³ãããã«ãã£ãŠã åœåã®èª²é¡ã§ãã£ãããããžã§ã¯ãã®ç®çãäœãéèŠèŠããŠããã®ãã®çè§£äžè¶³ããè£ãããšã«è²¢ç®ã§ãããšèšãããã§ã ã ãŸãããããã¯ãã«ã€ããŠããšã¬ããŒã¿ãŒãããã«ãã£ãŠè€æ°èгç¹ããè°è«ããããšã§ã以åããçè§£ãæ·±ãŸããŸããã ãã³ãã¬ãŒããæ±ºãŸã£ãŠããããšã«ãã£ãŠãèŠ³ç¹æŒããå°ãªãã®ãšã質åãã«ããããšãå
šãŠè°é¡ã«ä¹ããããšãã§ãã ã®ãè¯ãã£ãã§ããæ¬¡ã®å·¥çšã§ãããŠãŒã¶ãŒã¹ããŒãªãŒãããã³ã°ãè¡ãããã®æäœéã®å
±éèªèã®åœ¢æã«ã圹ç«ã¡ãŸããã äžæ¹ã§ çºèšã«åãããã ããŒã«ã®äœ¿ãæ¹ã«ã¯å°ãæžæã£ã æçµçãªãŸãšããããå°ããã£ãããããã ãšãã£ãæèŠãé ããŸããã çºèšã®åãã«ã€ããŠã¯ãç§ã®ãã¡ã·ãªããŒã·ã§ã³èœåãè¶³ããŠããªãã®ãšãã¯ãŒã¯ã·ã§ããã®æéã«ããšããæãããããšãã§ããªãã£ãããšãäžå ã ãšæããŸããæéã«è¿œãããŠããŠãé²è¡ãåªå
ããããŠããŸããã ãã¡ã·ãªããŒã·ã§ã³ã®éã«ã¯ã ã€ã³ã»ãã·ã§ã³ãããã宿ãããããšã ããç®çã§ã¯ãªããå
šå¡ã§ãã©ãããªè°è«ãããããšã»å
±éã®èªèãäœãããšãæèããããšãå€§äº ãšããåŠã³ããããŸããã ãŸããæåã« Miro ã®äœ¿ãæ¹ã«æ
£ããæéããæåŸã«ã€ã³ã»ãã·ã§ã³ãããå
šäœãæ¯ãè¿ãæéãèæ
®ããã¢ãžã§ã³ããäœæãããšããè¯ããã®ã«ãªãããã§ãã ãŸãšã æ°ããŒã ã®çºè¶³ã«ããããã€ã³ã»ãã·ã§ã³ãããã®äœæãè¡ãã«è³ã£ãçµç·¯ãšãã¯ãŒã¯ã·ã§ããã®å®æœæ¹æ³ããã®çµæåŸãããææãç¥èŠã«ã€ããŠæžããŸããã æ°ãããããžã§ã¯ããå§ããéãæ¢åã®ãããžã§ã¯ãã®æ¹åæ§ãææ§ã«ãªã£ãŠããŸã£ãŠãããšæããããŠããæ¹ã¯ãã€ã³ã»ãã·ã§ã³ãããã®äœæã«ææŠããŠã¿ããšäœããã®æãããã«ãªããããããŸããã æåŸãŸã§ãèªã¿é ãããããšãããããŸããã
ã¯ããã« ã¯ãããŸããŠã2021幎4ææ°åå
¥ç€Ÿã®åå±( @hrktcy )ã§ããããã¯ãšã³ããšã³ãžãã¢ãšããŠ6æã«ãã¯ãããžãŒã»ã³ã¿ãŒ Eng6G ã«æå±ããŸããã èæ¯ Eng6G ã§ã¯ ã¹ããã¬ãã£ã¬ã³ãž ãšåŒã°ãããµãŒãã¹ãããµãŒãã¬ã¹ãªã·ã¹ãã ãæ§ç¯ããŠéçºã»ä¿å®ã»éçšããŠããŸãããŸãããã¯ãšã³ãã«ã¯ Go ãæ¡çšããŠãããæ¯èŒçã¢ãã³ãªæè¡ã¹ã¿ãã¯ã«ãããããã¯ãéçºãè¡ãããŠããŸãã [åè]mediba ã«å
¥ç€Ÿãããã¢ãžã£ã€ã«å¿åã®ããŒã ã§æé«ã ã£ãä»¶ãã¢ãã¯ãŒã¯ç¡åã§ãã¬ã¯ãŒã¯ãè¶
è¶ããŸãã Go ã¯åºæ¬çã«æé»çå倿ãèªããããªããããéçºé¢é£ã®ã¿ã¹ã¯ãå
šãŠã¢ãã§è¡ãåŒããŒã ã«ãããŠãããã²ãŒã¿ãŒãã¬ãã¥ãŒãããããšããã¡ãªããããããŸãããŸãã¢ãã³ãªæè¡ãæ±ãããšã§ããšã³ãžãã¢ãšããŠã®åžå ŽäŸ¡å€ãé«ãŸããšèããŠããŸãã ããã§ Go æªçµéšã®ç§ãããã¯ãšã³ããšã³ãžãã¢ãšããŠãžã§ã€ã³ããã«ããããåŠç¿ãšã¢ãŠãããããå
ŒããŠãæ¬çš¿ã§ã¯Â Go ã§ã¹ã¯ã¬ã€ãã³ã°ãã mediba+  ã®èšäºã Slack ã«æçš¿ããããããäœã£ã話 ãåå¿é²ãšããŠæ®ããããšæããŸãã éçºç°å¢ M1 Mac Docker 20.10.7 Golang 1.14 Terraform 1.0.1 AWS provider 3.49.0 äºåæºå Slack API ããŒã¯ã³ãçæããŠãã Slack ã«æçš¿ãã App ãäœæããäºã API ããŒã¯ã³ãååŸããŠãããŸãã  Slack API  ãžã¢ã¯ã»ã¹ ã Create an app ããã¯ãªã㯠ã Create New App ããã¯ãªã㯠ã åå ããšã ã¯ãŒã¯ã¹ããŒã¹ ããæå®ãã ã¢ããªãäœæããåŸã«è¡šç€ºãããããŒãžã§ã Permissions ããã¯ãªã㯠ã Scopes ãã®é
ç®ã§Â chat:write 暩éãèšå® ã Install App to Workspace ããã¯ãªãã¯ã API ããŒã¯ã³ãååŸãã ãããã®ä»æ§ãåºãã Go ã§ã¹ã¯ã¬ã€ãã³ã°ãã mediba+ ã®èšäºã Slack ã«æçš¿ããã«ãããããŸãã¯ãããã®ä»æ§ãåºããããšã«ããŸããã ã¹ã¯ã¬ã€ãã³ã°æ¹æ³ ã¹ã¯ã¬ã€ãã³ã°ç³»ã®ããã±ãŒãž( goquery  , etc. )ãçšããããšãã§ããŸãããä»å㯠mediba+ ã® RSS ãã£ãŒããããŒã¹ããããšã§ã¹ã¯ã¬ã€ãã³ã°ãè¡ããŸããåœããåã§ããã¹ã¯ã¬ã€ãã³ã°å
ã®æ
å ±ãæŽæ°ããã床ã«ãã£ãŒãã®å
容ã¯å€æŽãããŸãããããå®è¡æç¹ã®æ¥æãšãã¹ã¯ã¬ã€ãã³ã°å
ã®èšäºæ¥æãåç
§ããå¿
èŠããããŸããããã§ä»åã¯ããããå®è¡æç¹ã®æ¥æã«æŽæ°ãããèšäºã®ã¿ã Slack ã«æçš¿ããããã«ããŸãã åäžèšäºãéè€ããŠæçš¿ããªã ããããå®è¡ãããã³ã«åäžèšäºãæçš¿ãããã®ã¯é¿ãããã§ããããã«ã€ããŠã¯ããŒãã«ã«ã¹ã¯ã¬ã€ãã³ã°ããèšäºæ
å ±ãæ ŒçŽããŠããã Slack ã«æçš¿ããæç« ãçæããåæ®µéã§ãèšäºãæçš¿ããããã®ãªã®ããå€å®ããå¿
èŠããããŸãã ãããã®éçšæ¹æ³ ãããããã°ã©ã ãä»»æã®æ¥æã«å®è¡ããããããªç°å¢ãæŽãããã§ããããã«ã€ããŠã¯ ECS Fargate + CloudWatch Events ã§ä»»æã®æ¥æã«ããããå®è¡ããããããªç°å¢ãæ§ç¯ããããšã§è§£æ±ºããŸããæ¬çš¿ã§ã¯ä»¥äžã®ã·ã¹ãã ãæ§ç¯ããŸãããæ¬ã·ã¹ãã 㯠Terraform ã«ãã£ãŠäžå
管çããŠããŸãã ãœãŒã¹ã³ãŒã 1. DB ãžæ¥ç¶ãã Go ã® OR ããããŒãšããŠæäŸãããŠãã gorm  ãçšããŠã env ãã¡ã€ã«ã«èšèŒãã DB ã®æ
å ±ããæ¥ç¶ãè¡ããŸãã DBTYPE := "mysql" USER := os.Getenv("USER") // ãŠãŒã¶å PASS := os.Getenv("PASS") // ãã¹ã¯ãŒã ENDPOINT := os.Getenv("ENDPOINT") //ãšã³ããã€ã³ã DBNAME := os.Getenv("DBNAME") //ããŒã¿ããŒã¹å CONNECT := USER+":"+PASS+"@tcp("+ENDPOINT+":3306)/"+DBNAME+"?charset=utf8&parseTime=True&loc=Local" db, err := gorm.Open(DBTYPE, CONNECT) if err != nil { fmt.Println("DBæ¥ç¶å€±æ") panic(err) } fmt.Println("DBæ¥ç¶æå") ä»åæ¥ç¶å
ã®ããŒãã«æ
å ±ã¯äžå³ã®éãã§ãã èšäºã¿ã€ãã«(title)ãš URL (link)ãæçš¿æžã¿å€å®(status)ã®3ã€ã®ã«ã©ã ãå®çŸ©ããŠãããŸãã 2. mediba+ ã®èšäºãã¹ã¯ã¬ã€ãã³ã°ãã RSS ãã£ãŒããããããå®è¡æã®æ¥æã«æçš¿ãããèšäºãã¹ã¯ã¬ã€ãã³ã°ãããŒãã«ãž insert ããŸãããã£ãŒãã®ååŸã«ã¯Â gofeed  ãçšããŸãã # mediba+ãã¹ã¯ã¬ã€ãã³ã°ãã fp := gofeed.NewParser() feed, _ := fp.ParseURL("https://koho.mediba.jp/feed/") 倿° feed ã«ã¯ããŒã¹ããããã£ãŒããæ ŒçŽãããŠããã feed.Items ã§æçš¿èšäºå
šãŠãååŸããããšãã§ããŸããä»åã¯ãããå®è¡æç¹ã®æ¥æã«æŽæ°ãããèšäºã®ã¿ãååŸããããã«ãèŠçŽ 1ã€1ã€ã for æã§åããåèšäºã®æçš¿æ¥æãšãããå®è¡æã®æ¥æãæ¯èŒããŸãã æ¯èŒããã«ããããããŒã¹ããã PubDate(UTC) 㯠string åãªã®ã§ time åãšæ¯èŒããããšãã§ãããã¹ã¯ã¬ã€ãã³ã°å
ã«ãã£ãŠã¯ãã©ãŒããããéãå¯èœæ§ãããããåãããŠãããå¿
èŠããããŸãããŸã PubDate ã JST ã«ããå¿
èŠããããŸãã ãã¡ãã«ã€ããŠã¯ RFC1123Z ãã©ãŒãããã§çµ±äžããŸããããŸã PubDate ã time.Parse ã§å€æããŸããããã«ããã RFC1123Z ã®ãã©ãŒãããã«å€æããã¿ã€ã ãŸãŒã³ã JST ã«ããããšã§ãæçš¿æ¥æãšãããå®è¡æã®æ¥æãæ¯èŒããŸããå
¬åŒãã©ãŒããã㯠ãã¡ã ããåç
§ã§ããŸãã // RSSæ§é äœ type Article struct { link string published string } // RSSã®PubDateãæååâæ¥æã®åã«å€æããããRFC1123Zã®Formatã«å€æããã¿ã€ã ãŸãŒã³ãJSTã«ãã for _, item := range feed.Items { m := make(map[string]Article) if item == nil { break } var timeParse = time.Time{} timeParse, _ = time.Parse(time.RFC1123Z, item.Published) pubDateJST := timeParse.In(time.FixedZone("Asia/Tokyo", 9*60*60)).Format(time.RFC1123Z) // 以äžInsertåŠç ... } æçš¿æ¥æãšãããå®è¡æã®æ¥æãåãæãæ§é äœ m ã«èšäºã®æ
å ±ãæ ŒçŽãã gorm ãçšããŠããŒãã«ã« insert ããã° OK ã§ãããã®ãšãã status ã«ã©ã ã«ã¯ããã©ã«ãå€ãšã㊠false ãå
¥ããŠãããŸãã 3. Slack ã«æçš¿ãã Slack ã«æçš¿ããåŠçã¯ä»¥äžã®éãã§ãã // envãã¡ã€ã«ã«èšèŒããAPIããŒã¯ã³ããã¯ã©ã€ã¢ã³ããçæãã tkn := os.Getenv("TOKEN") c := slack.New(tkn) _, _, err := c.PostMessage("#ãã£ã³ãã«å", slack.MsgOptionText( " ããã¹ã " , true)) if err != nil { panic(err) } else { fmt.Println("æçš¿å®äº") } ããŒãã«ã«æ ŒçŽãããŠãããæçš¿æ¥æããããå®è¡æã®æ¥æãšåãäžã€ status ã false ã®èšäºã®ã¿ã€ãã«ãšãªã³ã¯ãååŸãã slack.MsgOptionText ã®ç¬¬äžåŒæ°ã«ä»£å
¥ããŸããèšäº1ã€1ã€ã飿ãããš Slack ã®éç¥ãå€ããªãç
©ãããæããã®ã§ã string é
åã®äžã«ååŸããèšäºãšã¿ã€ãã«ã append ããŠããã strings ããã±ãŒãžã® strings.Join ãçšããŠãåèŠçŽ ãçµåããŠããæçš¿åŠçãè¡ãããã«ããŸããã æçš¿åŠçãå®äºããã gorm ãçšã㊠status ã«ã©ã ã®å€ã true ã« update ããããšã§ãããããå®è¡ãçŽããŠãåãèšäºãå床 Slack ã«æçš¿ããªãããã«ããŸãããŸãå
šãŠã®ã¯ãšãªæäœã¯ãã©ã³ã¶ã¯ã·ã§ã³å
ã§è¡ãããã«ããè¿ã£ãŠãã err ã nil ãã©ãããèŠãŠããŒã«ããã¯ãã³ãããã倿ããããã«ããŸãã å®è¡çµæ ç¡äºããããåäœããããšã確èªã§ããŸããã ãããã®å®è¡æéã¯å€§äœ1ç§ã§ããã ã€ãŸã¥ãããšãã Dockerfile ã®èšèš ãããããã°ã©ã ã§ã¯Â Go Modules  ãšããå€éšããã±ãŒãžç®¡çã·ã¹ãã ãçšããŠããŸã( Go Modules ã䜿çšããå Žåã Go ã®ããŒãžã§ã³ã¯1.11以äžã§ããå¿
èŠããããŸã)ãã Docker ã€ã¡ãŒãžããã«ãããéã«æ¯å Go Modules ã®ããŠã³ããŒããèµ°ãããããããã®å®è¡æéãé·ããªã£ãŠããŸããšããåé¡ããããŸããããŸã M1 mac ã§ãã«ããã Go ã€ã¡ãŒãžã ECR ã« Push ãããšãèªåçã« Go ã€ã¡ãŒãžã linux/arm çã«ãªã£ãŠããŸãããã§ãã(èšäºå·çæç¹)ããã¡ãã«ã€ããŠã¯ã Docker Buildx  㧠linux/amd64 ã§ãã«ãã ECR ã« Push ããããšã§å¯Ÿå¿ã§ããŸããããå®è¡æéåé¡ã¯è§£æ±ºããŠããŸããã ããã§Â Multistage Build Â ãæ¡çšããããšã«ããŸãããéçºç°å¢çšã®ã€ã¡ãŒãžã®äžã§ãã«ããè¡ããçæãããã·ã³ã°ã«ãã€ããªãæ¬çªç°å¢çšã® Alpine ã€ã¡ãŒãžã«ç§»ãããšã§ã倧å¹
ãªã¡ã¢ãªåæžãã§ããã ãã§ãªãå®è¡æéãççž®ããããšãå¯èœã§ãã FROM amd64/golang:1.15-alpine AS builder WORKDIR /go/src/tsuchiya COPY . /go/src/tsuchiya ENV GO111MODULE=on RUN CGO_ENABLED=0 GOOS=linux go build -o api main.go FROM alpine:latest WORKDIR /root/ COPY --from=builder /go/src/tsuchiya/api . CMD ["./api"] ã³ã³ãœãŒã«ãã ECR ã®ãã©ã€ããŒããªããžããªãèŠããŠã¿ãŸãã ã€ã¡ãŒãžãµã€ãºã確èªãããš100 MB 以äžåæžãããŠããããšãåãããŸããã ãããã« ã¹ã¯ã¬ã€ãã³ã°ãã mediba+ ã®ææ°èšäºã Slack ã«æçš¿ããããããäœããŸãããéçåä»ãèšèªã«èŠææèãæã£ãŠããç§ã§ããã Go ã¯æ§æãã·ã³ãã«ãªããããšãŠã楜ããå®è£
ãŸã§åãçµãããšãã§ããŸããã ãªããåç¥ã ãšã¯æããŸãããã¹ã¯ã¬ã€ãã³ã°ã¯çžæå
ã®ãµãŒãã«ã¢ã¯ã»ã¹ããããçæéã§å€§éã®ã¢ã¯ã»ã¹ãè¡ãã®ã¯ NG ã§ããè¿·æãããããªãããååé
æ
®ãããŸãããã æåŸã«ã mediba ã§ã¯äžç·ã«ã¢ãã¥ãããã§ãããšã³ãžãã¢ãåéããŠããŸãã å°ãã§ããèå³ããããŸããã ãã¡ã ããã©ããã
ããã«ã¡ã¯ããã¯ãããžãŒã»ã³ã¿ãŒ6Gã§ManagerãããŠããäžå°( @primunu )ã§ãã ã¡ã³ããŒãšã®éè«ã§ããŸã«è©±é¡ã«ãªããšã³ãžãã¢ã®ãã£ãªã¢ãã¹ã ã©ã®ãã£ãªã¢ãéžæãããã¯ãã¡ããåã
ãæ±ºå®ããŸãããæšä»ã®ãœãããŠã§ã¢ãšã³ãžãã¢ã®ãã£ãªã¢ãã¹ã¯å€æ§ãã€ãçµç¹ã«ãã£ãŠè¥å¹²åœ¹å²ãç°ãªãäºãããã®ã§ãç®æãæ¹åãããããè¿·åã«ãªãäºããããšçžè«ãåããŸããã ããã§äžåºŠç«ã¡æ»ããmedibaã§ã¯ã©ããªãã£ãªã¢ãã¹ãããã®ãïŒãŸããã©ã®ãããªåœ¹å²ãªã®ãïŒãæŽçãå«ãå³è§£ããŠã¿ãŸããã ãã£ãªã¢ãã¹ã®æŠèŠ åœ¹å²ãå³è§£ããæã23ã®ãã£ãªã¢ããããŸããã ãã®äžã§ãã€ã¡ãŒãžãä»ãã«ããããŸãã¯ä»ç€Ÿãšè¥å¹²é åã«ä¹é¢ããããã£ãªã¢ãéç¹çã«èª¬æããŠãããŸãã â» ãããŒãžã£ãŒ/PjMã¯ãã¡ããåç
§äžãã SRE äž»ãªæ¥åã¯AWSå
šäœç®¡çããã€ã³ãã©ç®¡çãæ§ç¯ãSLO/SLA/SLIã®å®çŸ©ãã»ãã¥ãªãã£ãããžã§ãã管çããã€ã«ã®æŽãåºãããã©ããã³ã°çãäž»ãªæ¥åã«ãªããŸãããªããIaCãã¢ãŒããã¯ãã£èšèšã¯ãªãŒãããã¯ãšã³ããšã³ãžãã¢ãããã¯ãªãŒãã宿œããäºãå€ãã§ãã ã€ã³ãã©çµç¹ããååãSREã«å€ãã£ãèæ¯ãããã®ã§ãSREãšããè·èœã®ã³ãããã¡ã³ãé åããŸã äžæç¢ºãšãã課é¡ããããçµç¹ã®çŽåŸåºŠãé«ããçºã«ãå®çŸ©ããããšèããŠããŸãã â» SRE奮éèš ã«ä»åŸèšèŒããŠãããŸãã ãªãŒããšã³ãžãã¢(ã»ãã¥ãªãã£ãšã³ãžãã¢å«) è±å¯ãªç¥èã»çµéšããæé©ãªã¢ãŒããã¯ãã£ãéžå®ããæè¡éžå®ãè¡ããªããPoCãåããæè¡ã§çœåŒããŠããã£ãªã¢ã«ãªããŸããåŸè¿°ããããã¯ãªãŒããšäŒŒãæ¯ãèãããŸãã 倧ããªéãã¯åœ±é¿ç¯å² ã«ãªããŸãããªãŒããšã³ãžãã¢ã®åœ±é¿ç¯å²ã¯ããŒã ã«ãªããŸãããããã¯ãªãŒãã¯çµç¹å
šè¬ã«åã³ãŸãã ãããŸã§èšè¿°ãããšãšã³ãžãã¢ãªã³ã°ããããªããšæãããã¡ã§ãããã¹ããŒã¯ãã«ããŒãšã®äŒè©±ãè¡ããåã¡ã³ããŒãžã®æç€ºãè¡ãã®ã§ã ãã ã³ãŒããæžããã£ãªã¢ ã§ã¯ãããŸããã ããã¯ãªãŒãäºåè»ã®ãã£ãªã¢ãªã®ã§ããã¯ãªãŒããšé£æºãããããã¯ãã®æè¡çæææ±ºå®ãè¡ããŸãã ã·ã¹ãã ãã£ã¬ã¯ã¿ãŒ medibaã§ã¯å®å
šèªç€Ÿéçºã®äŒç€Ÿã§ã¯ãªãããããã¯ãã«ãã£ãŠã¯åèšéçºããããŸãã çŸæç¹ã ãšåèšéçºãããã¯ãã®ã¿ã®ãã£ãªã¢ ã«ãªããããã§ã¹ããŒã¯ãã«ããŒãšæè¡ãã¬ããžã掻ãããªãããã£ã¬ã¯ã·ã§ã³ãè¡ããŸãããã£ã¬ã¯ã¿ãŒãšããäºãããææ¡ããèŠä»¶å®çŸ©ã¯ãã¡ããã®äºããã¡ã·ãªããŒã¿ãè¡ããŸããã¹ããŒã¯ãã«ããŒãååäŒç€Ÿã»å€éšäŒç€Ÿãšæè¡çãªäŒè©±ãã§ããæææ±ºå®ãã§ãå¿
èŠãããã®ã§ãããšã³ãžãã¢ã®äžçŽè·ã«ãªããšæããŠããŸãã ãããžã§ã¯ããªãŒã㌠ãããã¯ãã«ãã£ãŠPjMãšè²¬åã被ãäºããããŸãããéçºããŒã ãªã³ãªãŒã®ããŒã ãã8äººæªæºã®å°èŠæš¡ããŒã ã®ãªãŒããŒãmedibaã§èšããããžã§ã¯ããªãŒããŒã«ãªããŸãã ãµãŒãã³ããªãŒããŒã§ã¯ãªãåã«åºãŠåŒã£åŒµã£ãŠãããªãŒã㌠ãšãªããŸãã ã¹ããŒã¯ãã«ããŒãšã®äŒè©±ã¯ãã¡ããã®äºãã¹ã±ãžã¥ãŒã«ç®¡çããããŒã ãã«ãã£ã³ã°ãè¡ããŸããããŒã ã«ãã£ãŠã¯ã¹ã¯ã©ã ãã¹ã¿ãŒããããžã§ã¯ããªãŒããŒãå
Œä»»ããäºãå€ããšæããŠããŸããããŒãã¹ãã«ãšãœããã¹ãã«ã®äž¡é¢ãæ±ããããã®ã§ããããŒãžã£ãŒãç®æãæ¹ãéããã£ãªã¢ã«ãªããŸãããã¬ãããã©ã³ã¹ã§ããæèŠå€ãšããŠãã¬ãŒã€ãŒ7ããããŒãžã£ãŒ3ã§ã(åäººã®ææ³ã§ã)ã ãããªãããžã§ã¯ããªãŒããŒã§ããã ãããŒãžã£ãŒãšã®å€§ããªéãã¯ããŒãã«ãããŒãžã£ãŒãšçµç¹ãžã®ã³ãããã¡ã³ãã®æç¡ ã«ãªããŸããããŒã ãžã®ã³ãããã¡ã³ãã¯åœç¶ã§ãããçµç¹ãžã®å¹²æžã¯äœããããŒãã«ãããŒãžã¡ã³ãã¯çŽå±ãããŒãžã£ãŒã®è²¬åã«ãªããŸãã å質管çãªãŒã㌠å質管çã¯ã¹ãããã§å
¥ãäºãå€ããååäŒç€Ÿãšé£æºããäºãå€ãã§ããããã§è©Šéšé
ç®äœæãã¹ã±ãžã¥ãŒã«ç¢ºèªãSLAçã«åé¡ãªãã宿œã確èªãããšå¹³è¡ããååäŒç€Ÿãšã®é£æºãå¥çŽãçµ±çãè¡ãã®ãå質管çãªãŒããŒã«ãªããŸããå質管çã®ç¥è以å€ã«ãä»ç€Ÿã巻蟌ã¿çµç¹ããªããã°ããªãã®ã§ã ã¡ã³ããŒããŸãšãçµç¹ããã¹ãã« ãæ±ããããŸããE2Eãã¹ãã®ã·ããªãªãèšè¿°ãããå質管çã«ãããPDCAãåãæãŸã§ã¯ä»å
¥ã§ããŠãããä»åŸã®èª²é¡ãšãªã£ãŠããŸãã ãªããå質管çãšãã¹ã¿ãŒã®å€§ããªéãã¯èŠä»¶ãã詊éšé
ç®äœæãã§ããã®æç¡ã§ãã ããã¯ãªãŒã ããã¯ãªãŒããšã¯å®çµã«èšããšããªãŒããšã³ãžãã¢ã®äžäœè·ã«ãªãããªãŒããšã³ãžãã¢ã®ç®æã§ãè§ŠããŸãããã圱é¿ç¯å²ãçµç¹å
šè¬ãšãªããŸããå³å¯ã«ããã宿œããçã¯ãªããPjMã宿œããããPoCãåããããšæè¡çãªæææ±ºå®ãäž»å°ãæšé²ããŸããã³ãŒãã®å質管çã¯ãã¡ããã®äºãããŒã å
šäœã®çç£æ§ãã¢ãŒããã¯ãã£ã»èšèšãè¡ãã®ã§åºããšæ·±ãã®äž¡é¢ãæ±ããããŸãã ãªãã medibaã®ããã¯ãªãŒãã¯ãããŒãžã£ãŒã§ã¯ãªã ãæé·æ¯æŽçã¯è¡ãã¡ã³ã¿ãªã³ã°ã¯é©å®è¡ããã®ã®ã³ãããé åã§ã¯ãªãããããŸã§ãæè¡ã§ãªãŒãããããã¯ãã®æåã«å¯äžãããã£ãªã¢ã«ãªããŸãã UnitãããŒãžã£ãŒããããŒãžã£ãŒãã·ãã¢ãããŒãžã£ãŒãäœãéãã®ïŒ 现ããéãã¯ãããã®ã®ã 倧ããªéãã¯ç®¡èœããããŒã ã®çš®å¥ãšã³ãããé åãæ¯ç ã«ãªããŸãã UnitãããŒãžã£ãŒã¯ãããã¯ã暪æããŒã ããããŒãžã£ãŒãšã·ãã¢ãããŒãžã£ãŒã¯ãããã¯ãã«åŒ·ãé¢ãããããŒãžã£ãŒã«ãªããŸãããããŒãžã£ãŒãšã·ãã¢ãããŒãžã£ãŒã®åœ¹å²ã¯å€§ããå€ãããŸãããã ã·ãã¢ãããŒãžã£ãŒã®æ¹ãçµç¹ãžã®ã³ãããã¡ã³ã ãæ±ãããŸãã PO(ãããã¯ããªãŒããŒ)ããPM(ãããã¯ããããŒãžã£ãŒ)ã®ãã£ãªã¢ãã¹ã¯ïŒ Bizè·ããã®PO/PMã®ãã£ãªã¢ãã¹ã¯ãããã®ã®ãPOã®æ¥åç¯å²ã«ãšã³ãžãã¢ã«éŠŽæã¿ãèãPL管çãå«ãŸããŠããã®ãèµ·å ããŠãããããã ãšã³ãžãã¢ãšããŠã®PO/PMã®ãã£ãªã¢ãæããŠããŸãã ã ã翻蚳ããããã¯ããããžã¡ã³ããã©ã€ã¢ã³ã°ã« ã«ããããã«ããããã¯ãã¯éçºè
ããŠãŒã¶ãŒãããžãã¹ã® 3 ã€ã§æ§æãããŠããããšã³ãžãã¢èŠç¹ã¯å¿
èŠäžå¯æ¬ ã ãšèªèããŠããŸãã ãšã³ãžãã¢ãªã³ã°ãããŒã¿åæããšã³ãžãã¢ãšã®ã³ãã¥ãã±ãŒã·ã§ã³ãšèšã£ãé åãã«ããŒã§ããã®ã¯ãšã³ãžãã¢åºèº«ã®PO/PMã®åŒ·ã¿ã ãšæããŠããã ãããã¯ãã®æææ±ºå®ãçŽ æ©ã倿ã§ãã ãšæããŠããŸãã å
è¿°ã®éããŸã ãšã³ãžãã¢ã®ãã£ãªã¢ãšããŠæããŠããªãã®ãã®ãçŸå Žã§ã¯ãããŒãžã£ãŒããããã¯ãªãŒããäžå¿ãšãªããšã³ãžãã¢é åãã«ããŒããŠããŸãããã«ãã¿ã¹ã¯ã«ãªã£ãŠããŸãã®ã§ããã£ãªã¢ãã¹ã«ãªãäºãçµç¹èª²é¡ãšæããPO/PMã®ã³ãããé åãæç¢ºã«ãããã£ãªã¢ãã¹ãšããŠæããããšèããŠããŸãã ãŸãšã åŠäœã ã£ãã§ãããããè€éã«èŠãããã£ãªã¢ãã¹ã§ãããç®æãæ¹åã®ååŒãã§ããã°ãæ¥ã
ã®è¡åãå€ãããç®æšãåŒããŠã¯çµç¹ãžã®ã³ãããã¡ã³ããé«ããªããšèããŠããŸãã ãããæ°ã«ãã£ãªã¢ãã©ã³ãåèããŠã¿ãã®ã¯åŠäœã§ãããããå°ãã§ãæå©ãã«ãªãã°å¹žãã§ã
ã¯ããã« ããã«ã¡ã¯ãSRE Unitã®å浊ã§ãã ç§éãSRE掻åãæšé²ããŠããäžã§ãè¡ãè©°ãŸã£ãç¹ãéã«ããŸããã£ãæ¹æ³ãªã©ã®ç¥èŠãå
±æããŠããããšæããçãåããŸããã “ã¢ããªã±ãŒã·ã§ã³"ã®ã·ã¹ãã ãšã¯éãã"人"ã®ã·ã¹ãã ãæ¹åã»ä»å
¥ããŠããããã«ã¯ã é¢ä¿åè
ãžããããã®èª¬æãç¥èŠãå
±æããŠãããªããšãããªãã®ã¯åœç¶ã®ããšã éèŠãªãã€ã³ãã岿ããŠããŸããšãèŠãã¬èª€è§£ãçãã§ããŸããç©äºãããŸãæšé²ã§ããªããšããèªäœã«é¥ããŸãã ä»åã¯ãæã
ã®äœéšè«ãšããŠãšã©ãŒããžã§ãããšãããã®ããã¬ãã£ãã«èª€è§£ãããŠããŸã£ãéçšãšããã®è»éä¿®æ£ã«å¿
èŠã ã£ã説æããŸãšããŠã¿ãŸããã ãšã©ãŒããžã§ããã£ãŠäœã ãŸãã¯ãšã©ãŒããžã§ãããã®ãã®ã«ã€ããŠã足䞊ã¿ãæããŠãããŸãããã Googleã§æ€çŽ¢ãããããšä»¥äžã®ãããªèª¬æãåºãŠããŸãã ãšã©ãŒããžã§ããïŒError BudgetsïŒãšã¯ãšã©ãŒã«å¯Ÿããäºç®ã§ãããSLOã«åºã¥ãç®åºãããæå€±å¯èœãªä¿¡é Œæ§ã§ããã ãµãŒãã¹ã®èšæž¬ããã皌åæéãSLOãè¶
ããŠãããæèšããã°ãšã©ãŒããžã§ããããŸã æ®ã£ãŠããç¶æ
ã§ããã°ãããŒã ã¯æ°ãããªãªãŒã¹ãããã·ã¥ïŒãããã€ïŒã§ããã äŸãã°ãæ£åžžãªçšŒåæéãšããåãå£ã®SLIãèšå®ãããã®SLOã99.9%ãšå®çŸ©ãããšããŸãããã ããããå Žåãæ®ãã®0.1%ããšã©ãŒããžã§ããã«ãªããŸãã 100% - SLOïŒ99.9%ïŒ = 0.1% 1ã¶æã30æ¥éãšããå Žåãæ®ãã®0.1%ã¯43.2åã§ãã 1ã¶æ(43,200åïŒ/1000 = 43.2å ãã®å Žåãä»®ã«ããŠã³ã¿ã€ã ã1ã¶æã®ãã¡ã«43.2åæªæºã§ããã°æ°èŠéçºãç¶è¡ãã 43.2åãè¶
éããèªäœã«é¥ã£ãŠããå Žåã¯ãæ°èŠéçºãäžæãããã®å€ãå埩ãããŸã§ã®éã¯ããŠã³ã¿ã€ã ã®æéãæžããæŽ»åãè¡ãã ãã®ããã«äœ¿ãããã®ããšã©ãŒããžã§ããã§ãã çãŸãã誀解 ãšã©ãŒããžã§ããèªäœã¯DevãšOpsã®èª²é¡ãçµ¶åŠãªãã©ã³ã¹ã§è§£æ±ºããè¯ãææ³ãªã®ã§ããã ãããè¯ããã®ãšèªèããããã«ã¯ãããã€ãã®åæç¥èãå¿
èŠã§ããã å ããŠãäœã解決ããŠãããã®ãªã®ãã課é¡ãæããå¿
èŠããããŸãã åæç¥èãšèª²é¡ãããã®çžäºçè§£ããªããŸãŸå°å
¥ãææ¡ããŠãã ããã¡ã¯äºç®åã£ãŠåããŠãããããã¯ããªã®ã§ããªããªãæè»ã«èµåãããšã¯é£ããã ãçŽæããããããæ°èŠéçºäžæã¯å°ãã ããã¡ã¯çµç¹åœ¢æ
ãšããŠå€§ããããã»ã»ã»SREã£ãŠã¹ã¿ãŒãã¢ãããããã¯ãªãŒãã®ãããªäŒæ¥ã§å°å
¥ãããã€ã§ããïŒã …ãªã©ã®åå¿ãè¿ã£ãŠãããã§ãã äžèšã®åå¿ã¯ãèŠæ¹ã«ããã°è³æ¥µçã£åœã§ã ããããéçºãããã¯ããšããŠãéçºãžã®æè³ãä¿¡é Œæ§ã«åãããæ°èŠéçºã«åããããšãã£ãæææ±ºå®ã¯ããããã¯ãã®åœéãå·Šå³ããéèŠãªèŠçŽ ã§ãããã ãããªéèŠãªèŠçŽ ã®äžã€ããšã©ãŒããžã§ãããªããã®ã«èãé ããŠè¯ããã®ã§ããããã ããèãããšããªããªãå¿ççã«ãããŒãã«ãé«ããã§ãã ãšããããšã§ããšã©ãŒããžã§ãããçè§£ããããã®ç¥èŠããããŠäœã解決ãããŠå¬ããã®ããšãããã€ã³ãããµããŒã£ãŠãããããšæããŸãã æé»ã®ãšã©ãŒããžã§ãã ãšããã§ãã·ã¹ãã éçºã«é¢ããã®ããèªè
ã®æ¹ã«ã¯è³ªåãªã®ã§ããã ãããªããæ
åœããŠããã·ã¹ãã ã®ãšã©ãŒããžã§ããã¯æé©åãããŠããŸããïŒã ã» ã» ã» ãããããšã©ãŒããžã§ããå°å
¥ããŠããŒãã ãšèšãããŠããŸããããªã®ã§ããã å®ã¯ãããšãèšãåããªãã±ãŒã¹ãå€ãã®ã§ã¯ãªãããšæã£ãŠããŸãã äŸãã°ã ã·ã¹ãã ã«èŽåœçãªæ¬ é¥ãèŠã€ãããäºå®ããŠããéçºãäžæã ååŸ©äœæ¥ã«æ³šåããã ãšããç¶æ³ã¯ã€ã¡ãŒãžã§ããªãã§ããããã ãã®å Žåã¯ããšã©ãŒããžã§ããã倧å¹
ã«è¶
éããŠãããšããããšãã é¢ä¿è
å
šå¡ã®å
±éèªèãšãªã£ãæã«èµ·ããç¶æ
ã§ãã ã»ã»ã»ãµããããèãããšãã©ããããšã©ãŒããžã§ãããšãããã®ã¯ã æé»çã«ã¯ååšããŠãããã®ã®ããã§ãã æé»ã®ãšã©ãŒããžã§ãããåŒãèµ·ãããã® ãšã©ãŒããžã§ãããæé»çã§ãããã®ã®å Žåãèšãæããã°ã â人âããããã®æèŠå€ã«äŸåããŠããããšã«ãªããŸãã Aããã¯0.1%ã®æèŠãããããŸããããBããã¯0.01%ã®æèŠãããããŸããã ãããã¯ããšããŠã®æææ±ºå®ãè¡ãéããã®æèŠã®ä¹é¢ãåããææ®µã¯ã³ãã¥ãã±ãŒã·ã§ã³ã«ãªãããšãšæããŸããã ãã®æèŠå€ã¯å圹å²ã«ã圱é¿ãããããšãå€ãã ãããŠãæ£è§£ãååšããªããšãããå®ã«åä»ãªãšããã§æãããŸãããŠãããããã¯ããå€ãããããã§ãã ãããªããæ
åœããŠããã·ã¹ãã ã®ãšã©ãŒããžã§ããã¯æé©åãããŠããŸããïŒãããŠãã®æèŠã¯é¢ä¿è
åäœã§å
±éããŠãããã®ã§ããïŒã ãããããããããªãã®ããŒã ã¯ãã®æé»ã®ãšã©ãŒããžã§ããã®ã³ãã¥ãã±ãŒã·ã§ã³ã«å€å€§ãªå·¥æ°ãšåŽåã匷ããããŠããããããŸããã ãã®è³ªåã«Yesãšçãããããäžã€ãã³ãã¥ãã±ãŒã·ã§ã³ã宿
ã«èª²é¡ãæããŠããã®ã§ããã°ã ãããã¯ããšããŠæéãæ±ºããããšã«äžåºŠæ³šåãããšã©ãŒããžã§ããã®éçšãããŠã¿ãã®ãè¯ãéžæè¢ãããããŸãããã æ©èœæ§ãšä¿¡é Œæ§ããŠãŒã¶ãŒã¯ã©ã£ã¡ã欲ããïŒ äžã€ããšã©ãŒããžã§ããã®å¬ãã¿ãã€ã³ããèŠãããšããã§ããã 以äžã«ã極端ã§ããToDo管çã¢ããªã±ãŒã·ã§ã³ã®äŸãäºã€ãããŠã¿ãŸãã ã±ãŒã¹A ãŠãŒã¶ãŒãããè©äŸ¡ã®é«ãæ©èœæ§ã®ããã¢ããªã±ãŒã·ã§ã³ã ãã 3æ¥ã«1æ¥ãããã®ããŒã¹ã§å©çšãã§ããªããªãã ã±ãŒã¹B 24æé365æ¥æ£åžžã«çšŒåããããToDoã®ç»é²ãšåé€ã®æ©èœãããªã äžèšãã©ã¡ããã®ã¢ããªã±ãŒã·ã§ã³ã䜿ããããšæããŸããïŒ ã»ã»ã»ã©ã¡ãã䜿ããããªããšæã£ãããšã§ãããã å®éã«åžå Žã«åºããŠããŠãŒã¶ãŒããéžãã§ããããããšã¯ç¡ãããã§ãã ã€ãŸããããžãã¹ãšããŠãããã¯ããæåããã«ã¯ã æ°æ©èœã®éçºãšä¿¡é Œæ§ã®åäžãäž¡æ¹ã®ã¿ã¹ã¯ããã©ã³ã¹ãããããªã£ãŠãããªããã°ãªããªããã§ãã ããããããã§äºã€ç«ã¡å¡ããéå£ããããŸãã æ°æ©èœéçºãè¡ããšãã°ãçºçããå¯èœæ§ããããããä¿¡é Œæ§ãäœäžããã SLOã«9ãå ããã«ã¯ããã®åã®9ãå®è£
ããã®ã«ããã£ãã³ã¹ãã®10åãããã99%ãã99.9ïŒ
ã«ããããã«ã¯99%ã«ããããã«ããã£ãã³ã¹ãã®10åãããã99.99%ã«ããããã«ã¯ãããã®ããã«10åã®ã³ã¹ããããããšèšãããŠããŸãã ã©ãããæ°æ©èœéçºãšä¿¡é Œæ§ã®åäžã¯ããäºãã«ãã¬ãŒããªãã®é¢ä¿æ§ã«ããããã§ãã <åè> https://cloud.google.com/architecture/defining-SLOs?hl=ja#why_slos é«ãããSLOãåŒãèµ·ãããã® äŸãã°ãæé»çã«SLO99.99999…%ã®ããã«é«ãæ°Žæºã®SLOãèšå®ããŠããŸãã ãšã©ãŒããžã§ããããšãŠãå°ãªãç¶æ³äžã«ãã£ããšããŸãããã ãã®å Žåãä¿¡é Œæ§ã®æ
ä¿ã«å¯ŸããŠå¿
èŠãªã³ã¹ããããªãé«ãæ°Žæºã§å¿
èŠãšããã çµæçã«æ°èŠéçºãžã®çæãå°é£ãšããèªäœã«é¥ãããã§ãã ãã ãããããªç¶æ³äžã ã£ããšããŠãããããã¯ããšããŠæ°æ©èœéçºããŒããšããããšã¯èãã¥ããã§ãããã ä¿¡é Œæ§ãæ
ä¿ã§ããŠããªãç¶æ
ãªã®ã«æ°æ©èœãéçºããªãã¡ããããªããšãã倧å€ãªç¶æ³ã«ãªããããããŸããã æãåœããç¯ãããããã§ããã°ããŸãã¯ä»ã®ã·ã¹ãã ãã©ãã»ã©ã®æ°Žæºã§ä¿¡é Œæ§ãããã®ãã SLIãå®çŸ©ããèšæž¬ãããšããããå§ãããšè¯ãã§ãããã SLOããããŠããŸããšæ°èŠéçºã«æè³ã§ããã ãã®ã³ã¹ãã倱ãããŠããŸããšããåæã®ããšã å®çŸå¯èœæ§ãé«ãå€ãå®çŸ©ã§ãããšãå°ãã¥ã€æ°èŠéçºã«ãæè³ã§ããããã«ãªããããããŸããããããã§ãä»ã®çŸç¶ã§ä¿¡é Œæ§ãæ
ä¿ã§ããŠããªããšèããã®ã§ããã°ãå®éçãªææšã«ãã£ãŠãçŸåšè¡ã£ãŠããä¿¡é Œæ§åäžã®æœçã广ãããã®ããªãã®ãã倿ããããšãã§ããã§ãããã ãŸãšã ãã¬ãã£ããªè§£éããããã¡ãªãšã©ãŒããžã§ããã«é¢ããŠã ä»åã¯èª²é¡ã®èæ¯ã解決ã¢ãããŒãã説æãããŠããã ããŸãããã誀解ã¯è§£ããŸããã§ããããã ãšã©ãŒããžã§ãããå®çŸ©ããã®ã¯è¯ãããããšãã æ¹ããŠèªåã®æ
åœããŠãããããã¯ãã«ã¯ãç·æ¥çã«ã¯å¿
èŠãªãããããªã©ã諞ã
èããŠããããå¬ããã§ãã ãããã« medibaã§ã¯ãçŸåšãåãããã¯ãã®äŸ¡å€ãåäžãã¹ãã æ¥ã
SRE掻åãç©æ¥µçã«è¡ã£ãŠãããŸãã æ¬¡åã¯ããšã©ãŒããžã§ãããããæå¹ãªãã®ã«ããããã«ãä¿¡é Œæ§ãäžãããšäœãå¬ããã®ããäžãã£ãŠããŸããšã©ããªããšãèµ·ããããã®ããšããç¹ãæ·±å ãããã广ã®é«ãSLIå®çŸ©ã«ã€ããŠã®ãã¬ããžãå
±æãããããšèããŠãŸãããæ¥œãã¿ã«ã»ã»ã»ïŒ