Herokuã§ã®ãå©ç¨ã¯å ¬å¼ãµãã¼ãã®å¯¾è±¡å¤ã§ãã
Herokuã¯ã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ãåããããã®PaaSã§ãã ããã§ã¯ãMackerelãå©ç¨ãã¦Herokuä¸ã®ã¢ããªã±ã¼ã·ã§ã³ãç£è¦ããæ¹æ³ãç´¹ä»ãã¾ãã
ãã ããå ¬å¼ãµãã¼ã対象ã¨ã¯ãªã£ã¦ããã¾ããã®ã§ã使ç¨ä¸ã®ã質åçã«ãçãã§ãããã¾ãããªãã対å¿ç°å¢ã«ã¤ãã¦ã¯ãã¡ããã確èªãã ããã
Dynoãç£è¦ãã
Herokuã¯èªåã§ãã¹ã(Dyno)ã墿¸ãã¾ãã®ã§ãAuto Scalingç°å¢ã§ä½¿ãã®è¨å®ãHerokuã«åããã¦å©ç¨ãã¾ãã
Herokuã§ã¢ããªã±ã¼ã·ã§ã³ãèµ·åããããã® Procfile
ã§ã¯ãã·ã§ã«ã¹ã¯ãªãã start.sh
ãèµ·åããããã«ããstart.sh
ã®ä¸ã§å種è¨å®ãè¡ãã¾ãã
start.sh
ã® <API-KEY>
, <SERVICE>
, <ROLE>
ã¯é©åã«æ¸ãæãã¦ãã ããã
<RUN-APP>
ã¯ã¢ããªã±ã¼ã·ã§ã³ã®èµ·åã³ãã³ã(ä¾ãã°ãnode.jsã§ããã° node index.js
ãªã©)ã«æ¸ãæãã¦ãã ããã
- Procfile
web: ./start.sh
- start.sh
#!/bin/sh set -x # install mackerel-agent mackerel_agent=/app/mackerel-agent/mackerel-agent mackerel_agent_conf=/app/mackerel-agent/mackerel-agent.conf cd /app/ && \ curl -O http://file.mackerel.io/agent/tgz/mackerel-agent-latest.tar.gz && \ tar xvfz mackerel-agent-latest.tar.gz sh << SCRIPT cat > $mackerel_agent_conf <<'EOF'; pidfile = "/app/mackerel-agent/mackerel-agent.pid" root = "/app/mackerel-agent" apikey = "<API-KEY>" roles = [ "<SERVICE>:<ROLE>" ] EOF SCRIPT trap "$mackerel_agent retire -conf $mackerel_agent_conf -force" TERM $mackerel_agent -conf $mackerel_agent_conf -v & <RUN-APP>
ãµã¼ãã¹ã¡ããªãã¯ãæç¨¿ãã
Herokuã§ã¯Log Drainsã使ããã¨ã§ã¢ã¯ã»ã¹ãã°ãå«ãå種ãã°ãåå¾ã§ãã¾ãã
ããã§ã¯Herokuä¸ã®Railsã®ãã°ããã¬ã¹ãã³ã¹ã¿ã¤ã ã¨ã¨ã©ã¼ã¬ã¼ããè¨ç®ããMackerelã®ãµã¼ãã¹ã¡ããªãã¯ã«æç¨¿ããæ¹æ³ãç´¹ä»ãã¾ãã
Herokuã§Railsãåããæ¹æ³ã¯å ¬å¼ã¬ã¤ããåç §ãã¦ãã ããã
Railsã§JSONå½¢å¼ã®ãã°ãåºåãã
logrageãå©ç¨ãã¾ãã
# Gemfile gem 'lograge'
# config/application.rb module Testapp class Application < Rails::Application ... config.log_level = :info config.lograge.enabled = true config.lograge.formatter = Lograge::Formatters::Json.new ... end end
rsyslogãè¨å®ãã
rsyslogã¨fluentdãåãããã¹ããç¨æãã¾ããã¾ãã¯rsyslogã®è¨å®ãè¡ãã¾ãã5140çªãã¼ãã§Herokuããã®ãã°ãåãã¤ãã¾ãã®ã§ããã¡ã¤ã¢ã¦ã©ã¼ã«ã®è¨å®ã§5140çªãã¼ãã空ããããã«ãã¦ãã ããã
# /etc/rsyslog.conf $ModLoad imtcp $InputTCPServerRun 5140
Heroku Drainsãè¨å®ãã
<IPADDR>
ã¯rsyslogã¨fluentdãåãããã¹ãã®IPã¢ãã¬ã¹ã«ç½®æãã¦ãã ããã
# heroku drains:add syslog://<IPADDR>:5140 Successfully added drain syslog://<IPADDR>:5140
fluentdãè¨å®ãã
ã¾ãã¯td-agentãã¤ã³ã¹ãã¼ã«ãã¾ããå ¬å¼ã¬ã¤ãã«å¾ã£ã¦ãã ããã
次ã«å¿ è¦ãªãã©ã°ã¤ã³ãã¤ã³ã¹ãã¼ã«ãã¾ãã
# /usr/sbin/td-agent-gem install fluent-plugin-mackerel fluent-plugin-numeric-monitor fluent-plugin-datacounter
td-agentã®è¨å®ãã¡ã¤ã«ã«ä»¥ä¸ã追è¨ãã¾ãã <API-KEY>
ã¯APIãã¼ãã <APP>
ã¯æç¨¿å
ã®ãµã¼ãã¹åã«ç½®æãã¦ãã ããã
å¾åã®fluent-plugin-mackerelã®å©ç¨æ¹æ³ã®è©³ç´°ã¯fluentdã§ãµã¼ãã¹ã¡ããªãã¯ãæç¨¿ããããããã¦åç
§ãã¦ãã ããã
# /etc/td-agent/td-agent.conf <source> @type tail path /var/log/heroku pos_file /var/log/td-agent/posfile_heroku.pos format /^(?<time>[^ ]*\s+[^ ]*\s+[^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[a-zA-Z0-9\.]+)\])? *(?<message>.*)$/ time_format %b %d %H:%M:%S tag heroku.syslog </source> <match heroku.syslog> @type rewrite_tag_filter rewriterule1 message ^{" raw.heroku.access_log </match> <match raw.heroku.access_log> @type parser remove_prefix raw key_name message format json reserve_data true </match> <match heroku.access_log> @type copy <store> @type numeric_monitor count_interval 60s monitor_key duration output_per_tag yes percentiles 90,99 tag_prefix aggregated input_tag_remove_prefix heroku </store> <store> @type datacounter count_interval 60s count_key status output_per_tag yes pattern1 2xx ^2\d\d$ pattern2 3xx ^3\d\d$ pattern3 4xx ^4\d\d$ pattern4 5xx ^5\d\d$ outcast_unmatched yes tag_prefix status_aggregated input_tag_remove_prefix heroku </store> </match> <match status_aggregated.access_log> @type copy <store> @type rewrite_tag_filter capitalize_regex_backreference yes rewriterule1 2xx_count .+ status_count.access_log rewriterule2 3xx_count .+ status_count.access_log rewriterule3 4xx_count .+ status_count.access_log rewriterule4 5xx_count .+ status_count.access_log </store> <store> @type rewrite_tag_filter capitalize_regex_backreference yes rewriterule3 4xx_percentage .+ error_status_percentage.access_log rewriterule4 5xx_percentage .+ error_status_percentage.access_log </store> </match> <match status_count.access_log> @type mackerel flush_interval 60s api_key <API-KEY> out_keys 2xx_count,3xx_count,4xx_count,5xx_count remove_prefix service <APP> metrics_name access_num.${out_key} </match> <match aggregated.access_log> @type mackerel flush_interval 60s api_key <API-KEY> out_keys avg,percentile_90,percentile_99 remove_prefix service <APP> metrics_name access_latency.${out_key} </match> <match error_status_percentage.access_log> @type mackerel flush_interval 60s api_key <API-KEY> out_keys 4xx_percentage,5xx_percentage remove_prefix service <APP> metrics_name error_access_rate.${out_key} </match>
ãµã¼ãã¹ã¡ããªãã¯ã®ç£è¦ã«ã¼ã«ã追å ãã
æå¾ã«è¨å®ããã¬ã¹ãã³ã¹ã¿ã¤ã ã¨ã¨ã©ã¼ã¬ã¼ãã®ãµã¼ãã¹ã¡ããªãã¯ããããã«å¯¾ãã¦ãç£è¦ã«ã¼ã«ã追å ãã¾ãããã
å ·ä½çãªæ¹æ³ã¯ç£è¦ã»éç¥ãè¨å®ãããCLIãã¼ã« mkr ã使ããåç §ãã¦ãã ããã