This app plows data via several ways(syslog, api, client) and exposes metrics based on this data readable for Prometheus. Metrics are configurable via config file flexibly, see examples below.
The example of config:
input:
api:
- name: "some_api_input"
listenAddr: 9999
path: /some/api
template:
type: plain
pattern: "{{.http_code}} | {{.duration}} | {{.request}} | {{.method}}"
delimiter: "|"
metrics:
- name: requests_total
type: counter
help: "Total requests"
expr: '{{if ne .http_code "1"}}12{{else}}{{end}}'
value: "1"
labels:
- name: "http_code"
value: {{.http_code}}
- name: "method"
value: {{.method}}
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "1"
- name: response_time_milliseconds
type: summary
value: "{{.duration}}"
Ratibor supports the following types of templates:
plain
: is a one line data, the values in which are separated by delimiter. For example:value 1 | value 2 | value 3
. The delimiter is|
.
To evaluate metric value the two fields are used: expr
and value
. There are 3 cases of using this fields:
expr
andvalue
are not empty. In this case if evaluated expr is not empty, then ifvalue
can be considered as float64 value, it will be as metric value, else ifvalue
is not empty(i.e. it is some string), it will be asfloat(1)
as metric value, elsefloat(0)
:
Examples:
# http_code=200
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "1"
# nothing will be used as metric value
# http_code=100
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "1"
# float64(1) will be used as metric value
# http_code=100, page=/search
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "{{if eq .page "/page"}}2{{else}}3{{end}}"
# float64(2) will be used as metric value
# http_code=100, page=/product
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "{{if eq .page "/page"}}2{{else}}3{{end}}"
# float64(3) will be used as metric value
# http_code=100, page=/product
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}1{{end}}'
value: "{{if eq .page "/page"}}some_value{{else}}another_value{{end}}"
# float64(1) will be used as metric value
expr
is not empty, butvalue
is empty, then ifexpr
can be considered as float64, it will be as metric value, else ifexpr
is not empty(i.e. some string), thenfloat64(1)
value will be as metric value, else nothing will be exposed.
# http_code=100
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}2{{end}}'
# float64(2) will be used as metric value
# http_code=100
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}yes{{end}}'
# float64(1) will be used as metric value
# http_code=200
- name: errors_total
type: counter
help: "Total Errors"
expr: '{{if ne .http_code "200"}}yes{{end}}'
# nothing will be used as metric value
expr
is empty, butvalue
is not empty, then ifvalue
can be considered as float64, it will be as metric value, else ifvalue
is not empty,float64(1)
will be exposed as metric value elsefloat64(0)
will be exposed.
# page=/page
- name: errors_total
type: counter
help: "Total Errors"
value: "{{if eq .page "/page"}}2{{else}}3{{end}}"
# float64(2) will be used as metric value
# page=/product
- name: errors_total
type: counter
help: "Total Errors"
value: "{{if eq .page "/page"}}3{{end}}"
# float64(0) will be used as metric value
# page=/page
- name: errors_total
type: counter
help: "Total Errors"
value: "{{if eq .page "/page"}}yes{{end}}"
# float64(1) will be used as metric value
- name: handler_total_requests
type: counterVec
help: "Total requests by handler"
value: 1
labels:
- name: "status"
value: "{{.status}}"
- name: "handler"
values:
- expr: "{{if contains .request `blog`}}1{{end}}"
value: "{{ extractRegExp `\\/blog\\/[a-zA-Z-_\\/]+` .request }}"
- expr: "{{if eq .request `/`}}1{{end}}"
value: "home"
- value: "{{if contains .request `forum`}}{{ extractRegExp `\\/forum\\/[a-zA-Z-_\\/]+` .request }}{{end}}"
Input is a source of data. There are several types of inputs.
To set up syslog input add the following settings into configuration:
input:
syslog:
- name: "some_syslog_input"
listenAddr: ":9876"
To receive data via API it is needed to add the following configuration:
input:
api:
- name: "some_api_input"
listenAddr: ":9999"
path: "/my_input"