local typedefs = require "kong.db.schema.typedefs" local constants = require "kong.plugins.statsd.constants" local METRIC_NAMES = { "kong_latency", "latency", "request_count", "request_per_user", "request_size", "response_size", "status_count", "status_count_per_user", "unique_users", "upstream_latency", "status_count_per_workspace", "status_count_per_user_per_route", "shdict_usage", } local STAT_TYPES = { "counter", "gauge", "histogram", "meter", "set", "timer", } local CONSUMER_IDENTIFIERS = { "consumer_id", "custom_id", "username", } local SERVICE_IDENTIFIERS = { "service_id", "service_name", "service_host", "service_name_or_host", } local WORKSPACE_IDENTIFIERS = { "workspace_id", "workspace_name", } local DEFAULT_METRICS = { { name = "request_count", stat_type = "counter", sample_rate = 1, service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "latency", stat_type = "timer", service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "request_size", stat_type = "counter", sample_rate = 1, service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "status_count", stat_type = "counter", sample_rate = 1, service_identifier = nil, }, { name = "response_size", stat_type = "counter", sample_rate = 1, service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "unique_users", stat_type = "set", consumer_identifier = nil, service_identifier = nil, }, { name = "request_per_user", stat_type = "counter", sample_rate = 1, consumer_identifier = nil, service_identifier = nil, }, { name = "upstream_latency", stat_type = "timer", service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "kong_latency", stat_type = "timer", service_identifier = nil, consumer_identifier = nil, workspace_identifier = nil, }, { name = "status_count_per_user", stat_type = "counter", sample_rate = 1, consumer_identifier = nil, service_identifier = nil, }, { name = "status_count_per_workspace", stat_type = "counter", sample_rate = 1, workspace_identifier = nil, }, { name = "status_count_per_user_per_route", stat_type = "counter", sample_rate = 1, consumer_identifier = nil, service_identifier = nil, }, { name = "shdict_usage", stat_type = "gauge", sample_rate = 1, service_identifier = nil, }, } local TAG_TYPE = { "dogstatsd", "influxdb", "librato", "signalfx", } local MUST_IDENTIFIER = {} for _, metric in ipairs(DEFAULT_METRICS) do for _, id in ipairs({ "service", "consumer", "workspace"}) do if metric[id .. "_identifier"] then if not MUST_IDENTIFIER[id] then MUST_IDENTIFIER[id] = { metric.name } else MUST_IDENTIFIER[id][#MUST_IDENTIFIER[id]+1] = metric.name end end end end return { name = "statsd", fields = { { protocols = typedefs.protocols }, { config = { type = "record", fields = { { host = typedefs.host({ default = "localhost", description = "The IP address or hostname of StatsD server to send data to." }) }, { port = typedefs.port({ default = 8125, description = "The port of StatsD server to send data to." }) }, { prefix = { description = "String to prefix to each metric's name.", type = "string", default = "kong" }, }, { metrics = { description = "List of metrics to be logged.", type = "array", default = DEFAULT_METRICS, elements = { type = "record", fields = { { name = { description = "StatsD metric’s name.", type = "string", required = true, one_of = METRIC_NAMES }, }, { stat_type = { description = "Determines what sort of event a metric represents.", type = "string", required = true, one_of = STAT_TYPES }, }, { sample_rate = { description = "Sampling rate", type = "number", gt = 0 }, }, { consumer_identifier = { description = "Authenticated user detail.", type = "string", one_of = CONSUMER_IDENTIFIERS }, }, { service_identifier = { description = "Service detail.", type = "string", one_of = SERVICE_IDENTIFIERS }, }, { workspace_identifier = { description = "Workspace detail.", type = "string", one_of = WORKSPACE_IDENTIFIERS }, }, }, entity_checks = { { conditional = { if_field = "stat_type", if_match = { one_of = { "counter", "gauge" }, }, then_field = "sample_rate", then_match = { required = true }, }, }, }, }, }, }, { allow_status_codes = { description = "List of status code ranges that are allowed to be logged in metrics.", type = "array", elements = { type = "string", match = constants.REGEX_STATUS_CODE_RANGE, }, }, }, -- combine udp packet up to this value, don't combine if it's 0 -- 65,507 bytes (65,535 − 8 byte UDP header − 20 byte IP header) -- Wikipedia { udp_packet_size = { type = "number", between = {0, 65507}, default = 0 }, }, { use_tcp = { type = "boolean", default = false }, }, { hostname_in_prefix = { type = "boolean", default = false }, }, { consumer_identifier_default = { type = "string", required = true, default = "custom_id", one_of = CONSUMER_IDENTIFIERS }, }, { service_identifier_default = { type = "string", required = true, default = "service_name_or_host", one_of = SERVICE_IDENTIFIERS }, }, { workspace_identifier_default = { type = "string", required = true, default = "workspace_id", one_of = WORKSPACE_IDENTIFIERS }, }, { retry_count = { type = "integer", deprecation = { message = "statsd: config.retry_count no longer works, please use config.queue.max_retry_time instead", removal_in_version = "4.0", old_default = 10 }, }, }, { queue_size = { type = "integer", deprecation = { message = "statsd: config.queue_size is deprecated, please use config.queue.max_batch_size instead", removal_in_version = "4.0", old_default = 1 }, }, }, { flush_timeout = { type = "number", deprecation = { message = "statsd: config.flush_timeout is deprecated, please use config.queue.max_coalescing_delay instead", removal_in_version = "4.0", old_default = 2 }, }, }, { tag_style = { type = "string", required = false, one_of = TAG_TYPE }, }, { queue = typedefs.queue }, }, }, }, }, }