SRE ãã¼ã ã® @yuya-takeyama ã§ãã
Quipper ã® SRE ãã¼ã ã§ã¯ AWS ã Kubernetes ãç¨ããã¤ã³ãã©ã®æ§ç¯ãCI/CD ãã¤ãã©ã¤ã³ã®æ§ç¯ã»æ¹åçæ§ã 㪠Developer Experience ã®åä¸ã社å ã®ãããããµã¼ãã¹ã®ãã¤ã¯ããµã¼ãã¹åã®ãµãã¼ããããã¦ããã«ä¼´ãè¤éåã«ãèãå¾ãããããµã¼ãã¹ã®å®å®ç¨¼åãæ¯ããããã®ã«ã¼ã«ã»ãã¼ã«ç¾¤ãæ´åãã¦ãã¾ãã
ä»æ¥ã¯ãã®ä¸ã§ããç°¡åãã¤ãã精緻㫠Logs-Based Monitoring ãè¡ãããããGCP ã® Stackdrider Logging ã«æ§é åãã°ãéãæ¹æ³ã«ã¤ãã¦ç´¹ä»ãã¾ãã
æ§é åãã°ã¨ã¯
ããã§ã¯ã¨ãããããMachine-Readable ãªãã°ãã¨ãã¦å®ç¾©ãã¾ããé常ã®ãã°ã¯ããã¹ããã¼ã¹ã® Human-Readable ãªãã®ã§ãUNIX å²å¦ã«ããã¦ã¯è¡æåã®ããã¹ããã¡ã¤ã«ã¯ grep
çã®åç´ãªãã¼ã«ã¨ã®çµã¿åããã®å®¹ææ§ããåãã¨ããã¦ããã¨æãã¾ãã
ã§ãããè¡æåã®ããã¹ããã¼ã¿ã§ã¯è¤éãªæ§é ã®ãã¼ã¿ãæ±ãã®ã¯é£ããã§ããããæ£è¦è¡¨ç¾ç㧠parse ããã®ã¯ãã°ã®å½¢å¼ã«ãã£ã¦ã¯å°é£ã§ãã
ã¨ããããã§ä»åã¯ãã®ä¸¡æ¹ã®è¯ãã¨ãããã¨ã£ã¦è¡æåã® JSON ã使ç¨ãã¾ããç§ã¯ä»¥åãããã°ãæ¹è¡åºåãã® JSON ã§è¨é²ããææ³ã好ãã§ãã¾ãã
Stackdriver Logging ã¨ã¯
Stackdriver 㯠GCP ã®ãµã¼ãã¹ã§ãMonitoring ã Logging ã¨ãã£ã Observability ã確ä¿ããããã®æ©è½ç¾¤ãæã£ã¦ãã¾ãã
Stackdriver ã¯ä»ã§ãã Google ã«è²·åããã¦ãã¾ãããAWS ã«ã対å¿ãã¦ãããAWS ã§ã®ã»ããã¢ããæé ã«ã¤ãã¦ãå ¬å¼ã®ããã¥ã¡ã³ããç¨æããã¦ãã¾ãã
ã¾ããKubernetes ãã Stackdriver Logging ã«ãã°ãéä¿¡ããæé ã«ã¤ãã¦ã¯ Kubernetes ã®å ¬å¼ããã¥ã¡ã³ãã«è¨è¼ããã¦ãã¾ãã
ä»åã¯ãããæé ãå®äºããã¨ãããããã°ã¯ Stackdrider Logging ã«éãã¦ããç¶æ ãåæã¨ãã¦ãã¾ãã
JSON ã§ã® Logs-Based Monitoring ã®ä½ãå¬ããã
ã¾ã JSON ã«éãã Logs-Based Monitoring ã«é¢ãã¦ã§ãããã¢ãããã¯ãªåæã«ã¨ã¦ã便å©ã§ãã
å¾ã«ç´¹ä»ãã¾ãããäºåã«æ³å®ãã¦ããªãã£ãäºæ ã«éãã¦ããã°ããã¨ã«ã¨ããããã®ã¡ããªã¯ã¹ãä½æã»å¯è¦åãããã¨ã§ Fact-Based ãªææ決å®ãä½ã³ã¹ãã«è¡ããã¨ãã§ãã¾ãã
ã¾ããããã«ããã JSON ã§è¡ãã®ã¯ãè¤éãªæ§é ã®ãã¼ã¿ãåãæ±ããã¨ããã®ããã¡ããããã§ãããã¢ããªã±ã¼ã·ã§ã³ããã°åéåºç¤ã®ç¥èãæããªãã¦æ¸ã ã¨ããã®ã大ããã¨èãã¾ãã
ä¾ãã°åããã¨ã¯ Fluent Logger ã使ã£ã¦ Fluentd ã«ãã°ãéãã¤ãããã¨ãã§ãã¾ããããã®å ´åã¢ããªã±ã¼ã·ã§ã³ã¯ Fluentd ã«ã¤ãã¦ç¥ããªãã¦ã¯ãªãã¾ãããFluentd ã§ããã°ãã®å ã®ãã¼ã¿ã¹ãã¢ã®ãã¨ã¯é è½ãã¦ããã¾ãããä¾ãã°ãã°åéã®ãã¼ã«ã LogStash ã«å¤æ´ããããã¨ãã£ãå ´åãã¢ããªã±ã¼ã·ã§ã³å´ã¸ã®æ¹ä¿®ãå¿ è¦ã¨ãªã£ã¦ãã¾ãã¾ãã
ããããã¢ããªã±ã¼ã·ã§ã³ã¯ãã ãæ¹è¡åºåãã® JSON ãæ¨æºåºåã«æ¸ãè¾¼ãã°è¯ããã¨ããã°ãä¾ããã°åéãã¼ã«ãã³ã³ããåºç¤ãå¤ãã£ãã¨ãã¦ãé«ãåå©ç¨æ§ãæå¾ ã§ããã§ãããã
Fluentd ã§ãã°ä¸ã® JSON ã parse ãã
ä¸è¨ã® Kubernetes ã®ããã¥ã¡ã³ãã§ã¯ Fluentd ã使ã£ã¦ãKubernetes å ã® Docker ãåºåãããã°ãå¸ãåºãã¦ãã¾ãã
ãã®æã®ãã°ã¯ãã®ãããªæ¹è¡åºåãã® JSON ãã¼ã¿ã§ãã
{"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
ãã®ä¸ã® log
é¨åãã¢ããªã±ã¼ã·ã§ã³ãæ¨æºåºåã¾ãã¯æ¨æºã¨ã©ã¼åºåã«åºåãããã¼ã¿ã§ãã常㫠1 è¡ãã¤åºåããã¾ããããã Kubernetes ããã¥ã¡ã³ãä¸ã® Fluentd ã®ããã©ã«ãã®è¨å®ã§ã¯ä»¥ä¸ã®ããã«ãã¦åãåºãã¦ãã¾ãã
<source> type tail format json time_key time path /var/log/containers/*.log pos_file /var/log/gcp-containers.log.pos time_format %Y-%m-%dT%H:%M:%S.%N%Z tag reform.* read_from_head true </source> <filter reform.**> type parser format /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<log>.*)/ reserve_data true suppress_parse_error_log true key_name log </filter>
ã§ãããä»åã¯ãã®ãã°ãã¼ã¿ã«ããã« JSON ãå«ã¾ãã¦ãããã¨ãæ³å®ãã¾ããå®éã«ã¯ãã®ãããªãã°ã¨ãªãã§ãããã
{"log":"{\"foo\":\"FOO\"}\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
ãã®ããã«ãJSON ä¸ã«ããã« JSON ã¨ã³ã³ã¼ããããæååãå«ã¿ã¾ãããªã®ã§ãä¸è¨ã®è¨å®ã®å¾ã«ä»¥ä¸ã®ãããªè¨å®ã追å ãã¾ãã
<filter reform.**> @type parser format json key_name log reserve_data true hash_value_field _data </filter>
ããã§ããã log
ä¸ã®æååã JSON ã¨ãã¦ãã¼ã¹å¯è½ã§ããã°ãStackdriver Logging ä¸ã¯ jsonPayload
ã¨ãããã£ã¼ã«ãã®ä¸ã«ããã« _data
ã¨ãããã£ã¼ã«ããä½ã£ã¦æ§é åããããã°ãåãè¾¼ã¾ãã¾ãã
Rails ããæ§é åãã°ãåºåãã¦ã¿ã
ãã¨ã¯æ¨æºåºåãæ¨æºã¨ã©ã¼åºåã« JSON ãåºåããã ãã§ãããã ããæ¹è¡ã¯ããã« 1 ãã¼ã¿ããã 1 è¡ã«åããå¿ è¦ããããã¨ã«ã¯æ³¨æãå¿ è¦ã§ãã
ä»åã¯ãWeb ã¢ããªã±ã¼ã·ã§ã³ã®ããã¯ã°ã©ã¦ã³ãã§åä½ããã¨ãã Resque worker ã®ããã©ã¼ãã³ã¹åé¡ã調æ»ããããã«ä»¥ä¸ã®ãããªãã°ã追å ãã¦ã¿ã¾ããã 対象ã¦ã¼ã¶ã® ID ããå¦çãããã¼ã¿éçãè¨é²ãã¾ãã
log_data = { worker: self.to_s, data:{ user_id: user.id, duration: duration, organization_count: organizations.count, student_group_count: student_groups.count, student_count: students.count, } } Rails.logger.info(log_data.to_json)
worker
ã«ã¯ Resque worker ã®ã¯ã©ã¹åãduration
ã«ã¯å¦çæéã®ããªç§æ°ãæã£ã¦ãã¾ãã
ãããå ã«æ¤ç´¢ããã«ã¯ä»¥ä¸ã®ãããªã¯ã¨ãªãæ¸ãã°è¯ããã¨ã«ãªãã¾ããä¾ãã° FooWorker ã®å®è¡æéã 10 ç§ (10000 ããªç§) 以ä¸æéãããã£ã¦ãããã®ãæ½åºããå ´åã
jsonPayload._data.worker="FooWorker" jsonPayload._data.data.duration > 10000
(ã¹ã¯ã·ã§ä¸ãä¸é¨ Quipper ç¬èªã®è¨å®ã«ããæ¡ä»¶ãå«ã¾ããç¹ã«æ³¨æ)
ãã®ããã«ãå¿ è¦ãªãã¼ã¿ããã³ãã¤ã³ãã§åãåºãã¾ããã
ã¡ãªã¿ã«å®éã«ãã®ãã¼ã¿ãæ´»ç¨ãã¦ããã©ã¼ãã³ã¹ä¸åé¡ã«ãªããã¡ãªã¦ã¼ã¶ã®å¾åãç¹å®ããããã©ã¼ãã³ã¹åä¸ã®ããã®æ¹åãè¡ããããã¨ãã¦ããã¨ããã§ãã
ãããªãæ´»ç¨
Stackdriver ã§ã¯ Logs-Based metrics ã¨ãã¦ãã°ããã¡ããªã¯ã¹ãä½æãããã¨ãã§ãã¾ãããããããã¨ã«ã¢ã©ã¼ããé£ã°ããã¨ãã§ãã¾ãã
ã¡ããªã¯ã¹ã®ä½æã¯ãä¾ãã°æ£è¦è¡¨ç¾ã«ãããããè¡æ°ãã¨ãã£ããã®ã§ãå¯è½ãªã®ã§ãå¿ ãããæ§é åãã°ã§ããå¿ è¦ã¯ããã¾ãããããæ§é åãã°ã§ããã°ä¾ãã°ãã°ä¸ã®ããæ°å¤ã®åæ£ãå¯è¦åããããã§ããã®ã§ããã¯ãæ§é åãã¦ãããæ¹ãè²ã æ´»ç¨ãããããªãã§ãããã
ãã¡ãã¯å æ¥ãªãã¥ã¼ã¢ã«ããã¨ãã Single Page Application ã«ã¤ãã¦ãããªãã¥ã¼ã¢ã«åã®ãã¼ã¸ã§ã³ã®ã¢ããªã±ã¼ã·ã§ã³ããã®ã¢ã¯ã»ã¹ãæ¥ã¦ããããããã¨ãããã¨ãçºè¦ããæ¥é½ã©ããããæ¥ã¦ããã®ãã¨ããã®ãå¯è¦åããããã«ä½ã£ãã°ã©ãã§ãã (JSON é¢ä¿ãªãä¾)
ããããã¢ã¯ã»ã¹ã¯æ¥ã¦ãããã®ã®ãæ¥ã追ããã¨ã«é 調ã«æ¸ã£ã¦ããã®ã§ã¨ããããã¯é観ãã¨ããå¤æãä¸ããã¨ãã§ãã¾ããããã§ãããã§ããã
ãã®ä»ã«ããä¾ãã°åé¤äºå®ã®å®è£ ãæ¶ãåã«ã¹ã¿ãã¯ãã¬ã¼ã¹ä»ãã§ãã°ã®åºåããã¡ããªã¯ã¹ã®ä½æçãè¡ã£ã¦ããã°ãæå³ããå¼ã°ãã¦ãã¾ã£ã¦ãªããæ¤ç¥ããããã®ä»çµã¿ãé常ã«å®ä¾¡ã«ç¨æã§ããå ¥ãã¨ãæ§ã ãªæ´»ç¨ãã§ãããã§ãã
ã¨ãããã㧠Logs-Based Monitoring ã¯ã¨ã¦ã便å©ãªã®ã§ãæ¯éæ´»ç¨ãã¦ã¿ã¾ãããã