# outputs.conf module(load="omhttp") module(load="omstdout") ## TEMPLATES ## # Schema: "event-flatten:2" # Expects variables: # - $!data # Caller sets all subfields. template(name="tpl_event_flatten_v2" type="list") { constant(value="{\"schema_type\":\"json-schema\",\"schema_id\":\"event-flatten:2\",") constant(value="\"data\":") property(name="$!data") constant(value="}\n") } # Funnel Metric schema. # Expects variables: # - $!metric_service # - $!metric_name # - $!metric_tags # - $!metric_value # - $!metric_timestamp template(name="tpl_funnel_metrics" type="list") { constant(value="{") property(name="$!metric_service" outname="service" format="jsonfr") constant(value=",") constant(value="\"metricName\": [\"") property(name="$!metric_name") constant(value="\"],") constant(value="\"tags\":") property(name="$!metric_tags") constant(value=",") constant(value="\"metricValue\":") property(name="$!metric_value" format="json") constant(value=",") constant(value="\"timestamp\":") property(name="$!metric_timestamp" format="json") constant(value="}\n") } template(name="tpl_echo" type="string" string="%msg%") template(name="tpl_dynafile" type="list") { constant(value="<%= @data["log_drain"]["http_document_root"] %>/") property(name="$.dynadir") constant(value="/") property(name="$.app_id") constant(value=".") # App ID or Drain Token. property(name="$.source") constant(value=".") # Source. property(name="$.dyno") constant(value=".log") # Dyno. } template(name="tpl_dynafile_metrics" type="list") { constant(value="<%= @data["log_drain"]["http_document_root"] %>/") property(name="$.dynadir") constant(value="/") property(name="$!metric_service") constant(value="/") property(name="$!metric_name") constant(value="/") property(name="$!metric_tags!device") constant(value=".") property(name="$!metric_tags!source") constant(value=".") property(name="$!metric_tags!dyno") constant(value=".log") } ############## ## RULESETS ## ############## ruleset(name="rs_stdout") { action( type="omstdout" name="action_logger_omstdout" ) } ruleset(name="rs_funnel_dnr_logs" queue.size="<%= @data["log_drain"]["output_queue_size"] %>" <%- if @data["log_drain"]["logs_output_batch_size"] -%> queue.dequeueBatchSize="<%= @data["log_drain"]["logs_output_batch_size"] %>" <%- end -%> <%- if @data["log_drain"]["logs_output_min_batch_size"] -%> queue.minDequeueBatchSize="<%= @data["log_drain"]["logs_output_min_batch_size"] %>" <%- end -%> queue.minDequeueBatchSize.timeout="<%= @data["log_drain"]["logs_batch_timeout_ms"] %>" queue.workerthreads="<%= @data["log_drain"]["logs_batch_worker_threads"] %>" ) { <%- if @data["log_drain"]["debug"] -%> set $.dynadir = "funnel-dnr"; action( type="omfile" template="tpl_event_flatten_v2" dynafile="tpl_dynafile" ) <%- end -%> <%- if @data["log_drain"]["publish_logs"] -%> action( name="action_omhttp_funnel_dnr_logs" type="omhttp" template="tpl_event_flatten_v2" server="<%= @data["_funnel_logs"]["host"] %>" serverport="<%= @data["_funnel_logs"]["port"] %>" checkpath="funnel/ping" restpath="v1/logs/v1/dnr/heroku/v1" <%- if @data["_funnel"]["dnr_request_timeout_ms"] -%> restpathtimeout="<%= @data["_funnel"]["dnr_request_timeout_ms"] %>" <%- end -%> action.resumeInterval="<%= @data["_funnel"]["request_resume_interval_secs"] %>" action.resumeIntervalMax="<%= @data["_funnel"]["request_resume_interval_max_secs"] %>" httpcontenttype="application/vnd.kafka.json.v1+json" batch.format="jsonarray" batch="on" batch.maxsize="<%= @data["log_drain"]["logs_batch_size"] %>" batch.maxbytes="<%= @data["log_drain"]["logs_batch_max_bytes"] %>" tls.cacert="<%= @data["_pki"]["cacert"] %>" tls.mycert="<%= @data["_pki"]["client"]["cert"] %>" tls.myprivkey="<%= @data["_pki"]["client"]["key"] %>" usehttps="on" compress="on" retry="on" retry.ruleset="rs_funnel_dnr_logs_retry" ) <%- end -%> } ruleset(name="rs_funnel_dnr_logs_retry") { action( name="action_omhttp_funnel_dnr_logs_retry" type="omhttp" queue.size="1000" template="tpl_echo" server="<%= @data["_funnel_logs"]["host"] %>" serverport="<%= @data["_funnel_logs"]["port"] %>" checkpath="funnel/ping" restpath="v1/logs/v1/dnr/heroku/v1" <%- if @data["_funnel"]["dnr_request_timeout_ms"] -%> restpathtimeout="<%= @data["_funnel"]["dnr_request_timeout_ms"] %>" <%- end -%> action.resumeInterval="<%= @data["_funnel"]["request_resume_interval_secs"] %>" action.resumeIntervalMax="<%= @data["_funnel"]["request_resume_interval_max_secs"] %>" httpcontenttype="application/vnd.kafka.json.v1+json" batch.format="jsonarray" batch="on" batch.maxsize="<%= @data["log_drain"]["logs_batch_size"] %>" batch.maxbytes="<%= @data["log_drain"]["logs_batch_max_bytes"] %>" tls.cacert="<%= @data["_pki"]["cacert"] %>" tls.mycert="<%= @data["_pki"]["client"]["cert"] %>" tls.myprivkey="<%= @data["_pki"]["client"]["key"] %>" usehttps="on" compress="on" retry="on" retry.ruleset="rs_funnel_dnr_logs_retry" ) } ruleset( name="rs_funnel_logs" queue.size="<%= @data["log_drain"]["output_queue_size"] %>" <%- if @data["log_drain"]["logs_output_batch_size"] -%> queue.dequeueBatchSize="<%= @data["log_drain"]["logs_output_batch_size"] %>" <%- end -%> <%- if @data["log_drain"]["logs_output_min_batch_size"] -%> queue.minDequeueBatchSize="<%= @data["log_drain"]["logs_output_min_batch_size"] %>" <%- end -%> queue.minDequeueBatchSize.timeout="<%= @data["log_drain"]["logs_batch_timeout_ms"] %>" queue.workerthreads="<%= @data["log_drain"]["logs_batch_worker_threads"] %>" ) { <%- if @data["log_drain"]["debug"] -%> set $.dynadir = "funnel-logs"; action( type="omfile" template="tpl_event_flatten_v2" dynafile="tpl_dynafile" ) <%- end -%> <%- if @data["log_drain"]["publish_logs"] -%> action( name="action_omhttp_funnel_logs" type="omhttp" <%- if @data["log_drain"]["logs_use_sender_thread"] -%> senderthread.maxconnections="<%= @data["log_drain"]["logs_sender_max_connections"] %>" senderthread="on" <%- end -%> template="tpl_event_flatten_v2" server="<%= @data["_funnel_logs"]["host"] %>" serverport="<%= @data["_funnel_logs"]["port"] %>" checkpath="funnel/ping" restpath="<%= @data["_funnel_logs"]["rest_path"] -%>" <%- if @data["_funnel"]["logs_request_timeout_ms"] -%> restpathtimeout="<%= @data["_funnel"]["logs_request_timeout_ms"] %>" <%- end -%> action.resumeInterval="<%= @data["_funnel"]["request_resume_interval_secs"] %>" action.resumeIntervalMax="<%= @data["_funnel"]["request_resume_interval_max_secs"] %>" httpcontenttype="<%= @data["_funnel_logs"]["http_content_type"] %>" batch.format="<%= @data["_funnel_logs"]["batch_format"] %>" batch="on" batch.maxsize="<%= @data["log_drain"]["logs_batch_size"] %>" batch.maxbytes="<%= @data["log_drain"]["logs_batch_max_bytes"] %>" tls.cacert="<%= @data["_pki"]["cacert"] %>" tls.mycert="<%= @data["_pki"]["client"]["cert"] %>" tls.myprivkey="<%= @data["_pki"]["client"]["key"] %>" usehttps="on" compress="on" retry="on" retry.ruleset="rs_funnel_logs_retry" ) <%- end -%> } ruleset(name="rs_funnel_logs_retry") { action( name="action_omhttp_funnel_logs_retry" type="omhttp" queue.size="1000" template="tpl_echo" server="<%= @data["_funnel_logs"]["host"] %>" serverport="<%= @data["_funnel_logs"]["port"] %>" checkpath="funnel/ping" restpath="<%= @data["_funnel_logs"]["rest_path"] -%>" <%- if @data["_funnel"]["logs_request_timeout_ms"] -%> restpathtimeout="<%= @data["_funnel"]["logs_request_timeout_ms"] %>" <%- end -%> action.resumeInterval="<%= @data["_funnel"]["request_resume_interval_secs"] %>" action.resumeIntervalMax="<%= @data["_funnel"]["request_resume_interval_max_secs"] %>" httpcontenttype="<%= @data["_funnel_logs"]["http_content_type"] %>" batch.format="<%= @data["_funnel_logs"]["batch_format"] %>" batch="on" batch.maxsize="<%= @data["log_drain"]["logs_batch_size"] %>" batch.maxbytes="<%= @data["log_drain"]["logs_batch_max_bytes"] %>" tls.cacert="<%= @data["_pki"]["cacert"] %>" tls.mycert="<%= @data["_pki"]["client"]["cert"] %>" tls.myprivkey="<%= @data["_pki"]["client"]["key"] %>" usehttps="on" compress="on" retry="on" retry.ruleset="rs_funnel_logs_retry" ) } # Ruleset to publish metrics to Funnel with expected scoping tags. # Sends 2 metrics for each call to maintain backwards compatibility with current scopes. # 1. "..HEROKU." # 2. ".EXT.HEROKU." # TODO: Remove (2) after some amount of time. # Reference https://salesforce.quip.com/PKsXAasFQQ8R ruleset(name="rs_funnel_metrics") { reset $!metric_tags!datacenter = "<%= @data["heroku"]["short_region"] %>"; reset $!metric_tags!superpod = "heroku"; reset $!metric_tags!pod = "<%= @data["heroku"]["app_name"] %>"; call rs_funnel_metrics_internal reset $!metric_tags!datacenter = "ext"; call rs_funnel_metrics_internal } # Internal ruleset to publish metrics to Funnel. # Note! It's important that the omhttp action sets action.copymsg="on", # since we call it multiple times for the same event. ruleset(name="rs_funnel_metrics_internal") { <%- if @data["log_drain"]["debug"] -%> set $.dynadir = "funnel-metrics"; action( type="omfile" template="tpl_funnel_metrics" dynafile="tpl_dynafile_metrics" ) <%- end -%> <%- if @data["log_drain"]["publish_metrics"] -%> action( name="action_omhttp_funnel_metrics" type="omhttp" action.copymsg="on" queue.size="10000" template="tpl_funnel_metrics" server="<%= @data["_funnel"]["host"] %>" serverport="<%= @data["_funnel"]["port"] %>" checkpath="funnel/ping" restpath="v1/metrics/v2" restpathtimeout="<%= @data["_funnel"]["metrics_request_timeout_ms"] %>" action.resumeInterval="<%= @data["_funnel"]["request_resume_interval_secs"] %>" action.resumeIntervalMax="<%= @data["_funnel"]["request_resume_interval_max_secs"] %>" httpcontenttype="application/json" batch.format="jsonarray" batch="on" batch.maxsize="500" batch.maxbytes="1000000" tls.cacert="<%= @data["_pki"]["cacert"] %>" tls.mycert="<%= @data["_pki"]["client"]["cert"] %>" tls.myprivkey="<%= @data["_pki"]["client"]["key"] %>" usehttps="on" compress="on" retry="off" ) <%- end -%> }