daemon: expose prometheus in new global.monitoring config section + document it

refs #67
This commit is contained in:
Christian Schwarz 2018-04-14 11:24:47 +02:00
parent a4da029105
commit 82ea535692
10 changed files with 71 additions and 10 deletions

View File

@ -12,6 +12,7 @@ import (
) )
type PrometheusJob struct { type PrometheusJob struct {
Name string
Listen string Listen string
} }
@ -55,12 +56,10 @@ func parsePrometheusJob(c JobParsingContext, name string, i map[string]interface
if s.Listen == "" { if s.Listen == "" {
return nil, errors.New("must specify 'listen' attribute") return nil, errors.New("must specify 'listen' attribute")
} }
return &PrometheusJob{s.Listen}, nil return &PrometheusJob{name, s.Listen}, nil
} }
func (*PrometheusJob) JobName() string { func (j *PrometheusJob) JobName() string { return j.Name }
return "prometheus"
}
func (j *PrometheusJob) JobType() JobType { return JobTypePrometheus } func (j *PrometheusJob) JobType() JobType { return JobTypePrometheus }

View File

@ -93,9 +93,30 @@ func parseConfig(i interface{}) (c *Config, err error) {
cpc := ConfigParsingContext{&c.Global} cpc := ConfigParsingContext{&c.Global}
jpc := JobParsingContext{cpc} jpc := JobParsingContext{cpc}
// Jobs
c.Jobs = make(map[string]Job, len(asMap.Jobs)) c.Jobs = make(map[string]Job, len(asMap.Jobs))
// FIXME internal jobs should not be mixed with user jobs
// Monitoring Jobs
var monJobs []map[string]interface{}
if err := mapstructure.Decode(asMap.Global["monitoring"], &monJobs); err != nil {
return nil, errors.Wrap(err, "cannot parse monitoring section")
}
for i, jc := range monJobs {
if jc["name"] == "" || jc["name"] == nil {
// FIXME internal jobs should not require a name...
jc["name"] = fmt.Sprintf("prometheus-%d", i)
}
job, err := parseJob(jpc, jc)
if err != nil {
return nil, errors.Wrapf(err, "cannot parse monitoring job #%d", i)
}
if job.JobType() != JobTypePrometheus {
return nil, errors.Errorf("monitoring job #%d has invalid job type", i)
}
c.Jobs[job.JobName()] = job
}
// Regular Jobs
for i := range asMap.Jobs { for i := range asMap.Jobs {
job, err := parseJob(jpc, asMap.Jobs[i]) job, err := parseJob(jpc, asMap.Jobs[i])
if err != nil { if err != nil {
@ -109,7 +130,7 @@ func parseConfig(i interface{}) (c *Config, err error) {
} }
jn := job.JobName() jn := job.JobName()
if _, ok := c.Jobs[jn]; ok { if _, ok := c.Jobs[jn]; ok {
err = errors.Errorf("duplicate job name: %s", jn) err = errors.Errorf("duplicate or invalid job name: %s", jn)
return nil, err return nil, err
} }
c.Jobs[job.JobName()] = job c.Jobs[job.JobName()] = job

View File

@ -17,7 +17,7 @@ func TestSampleConfigsAreParsedWithoutErrors(t *testing.T) {
"./sampleconf/pullbackup/backuphost.yml", "./sampleconf/pullbackup/backuphost.yml",
"./sampleconf/pullbackup/productionhost.yml", "./sampleconf/pullbackup/productionhost.yml",
"./sampleconf/random/debugging.yml", "./sampleconf/random/debugging.yml",
"./sampleconf/random/logging.yml", "./sampleconf/random/logging_and_monitoring.yml",
} }
for _, p := range paths { for _, p := range paths {

View File

@ -20,5 +20,9 @@ global:
level: debug level: debug
format: logfmt format: logfmt
monitoring:
- type: prometheus
listen: ':9090'
jobs: [] jobs: []

View File

@ -10,6 +10,11 @@ Changelog
The changelog summarized bugfixes that are deemed relevant for users. The changelog summarized bugfixes that are deemed relevant for users.
Developers should consult the git commit log or GitHub issue tracker. Developers should consult the git commit log or GitHub issue tracker.
0.0.4 (unreleased)
------------------
* |feature| :issue:`67`: Expose `Prometheus <https://prometheus.io>`_ metrics via HTTP (:ref:`config docs <monitoring-prometheus>`)
0.0.3 0.0.3
----- -----

View File

@ -13,4 +13,5 @@ Configuration
configuration/map_filter_syntax configuration/map_filter_syntax
configuration/prune configuration/prune
configuration/logging configuration/logging
configuration/monitoring
configuration/misc configuration/misc

View File

@ -8,7 +8,7 @@ Logging
zrepl uses structured logging to provide users with easily processable log messages. zrepl uses structured logging to provide users with easily processable log messages.
Logging outlets are configured in the ``global`` section of the |mainconfig|. Logging outlets are configured in the ``global`` section of the |mainconfig|.
Check out :sampleconf:`random/logging.yml` for an example on how to configure multiple outlets: Check out :sampleconf:`random/logging_and_monitoring.yml` for an example on how to configure multiple outlets:
:: ::

View File

@ -0,0 +1,30 @@
.. include:: ../global.rst.inc
.. _monitoring:
Monitoring
==========
Monitoring endpoints are configured in the ``global.monitoring`` section of the |mainconfig|.
Check out :sampleconf:`random/logging_and_monitoring.yml` for examples.
.. _monitoring-prometheus:
Prometheus
----------
zrepl can expose `Prometheus metrics <https://prometheus.io/docs/instrumenting/exposition_formats/>`_ via HTTP.
The ``listen`` attribute is a `net.Listen <https://golang.org/pkg/net/#Listen>`_ string for tcp, e.g. ``:9091`` or ``127.0.0.1:9091``.
The Prometheues monitoring job appears in the ``zrepl control`` job list and may be specified **at most once**.
There is no stability guarantee on the exported metrics.
::
global:
monitoring:
- type: prometheus
listen: ':9091'

View File

@ -193,6 +193,7 @@ Summary
Congratulations, you have a working pull backup. Where to go next? Congratulations, you have a working pull backup. Where to go next?
* Read more about :ref:`configuration format, options & job types <configuration_toc>` * Read more about :ref:`configuration format, options & job types <configuration_toc>`
* Configure :ref:`logging <logging>` \& :ref:`monitoring <monitoring>`.
* Learn about :ref:`implementation details <implementation_toc>` of zrepl. * Learn about :ref:`implementation details <implementation_toc>` of zrepl.

View File

@ -37,7 +37,7 @@ zrepl daemon
============ ============
All actual work zrepl does is performed by a daemon process. All actual work zrepl does is performed by a daemon process.
Logging is configurable via the config file. Please refer to the :ref:`logging documention <logging>`. The daemon supports structured :ref:`logging <logging>` and provides :ref:`monitoring endpoints <monitoring>`.
When installating from a package, the package maintainer should have provided an init script / systemd.service file. When installating from a package, the package maintainer should have provided an init script / systemd.service file.
You should thus be able to start zrepl daemon using your init system. You should thus be able to start zrepl daemon using your init system.