feat(server): ability to disable metrics
ci/woodpecker/pr/docs Pipeline was successful Details
ci/woodpecker/pr/lint Pipeline was successful Details
ci/woodpecker/pr/build Pipeline was successful Details
ci/woodpecker/pr/man Pipeline was successful Details
ci/woodpecker/pr/docker Pipeline was successful Details
ci/woodpecker/pr/test Pipeline was successful Details

Jef Roosens 2022-12-28 17:39:45 +01:00 committed by Chewing_Bever
parent 4041d02760
commit 2edf5be900
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 26 additions and 8 deletions

View File

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://git.rustybever.be/vieter-v/vieter/src/branch/dev) ## [Unreleased](https://git.rustybever.be/vieter-v/vieter/src/branch/dev)
### Added
* Metrics endpoint for Prometheus integration
## [0.5.0-rc.2](https://git.rustybever.be/vieter-v/vieter/src/tag/0.5.0-rc.2) ## [0.5.0-rc.2](https://git.rustybever.be/vieter-v/vieter/src/tag/0.5.0-rc.2)
### Added ### Added

View File

@ -3,14 +3,17 @@ module server
import metrics import metrics
import web import web
// v1_metrics serves a Prometheus-compatible metrics endpoint.
['/api/v1/metrics'; get] ['/api/v1/metrics'; get]
fn (mut app App) v1_metrics() web.Result { fn (mut app App) v1_metrics() web.Result {
if !app.conf.collect_metrics {
return app.status(.not_found)
}
mut exporter := metrics.new_prometheus_exporter([0.01, 0.05, 0.1, 0.5, 1, 100]) mut exporter := metrics.new_prometheus_exporter([0.01, 0.05, 0.1, 0.5, 1, 100])
exporter.load(app.collector) exporter.load(app.collector)
// TODO stream to connection instead // TODO stream to connection instead
body := exporter.export_to_string() or { body := exporter.export_to_string() or { return app.status(.internal_server_error) }
return app.status(.internal_server_error)
}
return app.body(.ok, 'text/plain', body) return app.body(.ok, 'text/plain', body)
} }

View File

@ -15,6 +15,7 @@ pub:
base_image string = 'archlinux:base-devel' base_image string = 'archlinux:base-devel'
max_log_age int = -1 max_log_age int = -1
log_removal_schedule string = '0 0' log_removal_schedule string = '0 0'
collect_metrics bool [empty_default]
} }
// cmd returns the cli submodule that handles starting the server // cmd returns the cli submodule that handles starting the server

View File

@ -101,14 +101,20 @@ pub fn server(conf Config) ! {
util.exit_with_message(1, 'Failed to initialize database: $err.msg()') util.exit_with_message(1, 'Failed to initialize database: $err.msg()')
} }
collector := if conf.collect_metrics {
&metrics.MetricsCollector(metrics.new_default_collector())
} else {
&metrics.MetricsCollector(metrics.new_null_collector())
}
mut app := &App{ mut app := &App{
logger: logger logger: logger
api_key: conf.api_key api_key: conf.api_key
conf: conf conf: conf
repo: repo repo: repo
db: db db: db
collector: collector
job_queue: build.new_job_queue(global_ce, conf.base_image) job_queue: build.new_job_queue(global_ce, conf.base_image)
collector: metrics.new_default_collector()
} }
app.init_job_queue() or { app.init_job_queue() or {
util.exit_with_message(1, 'Failed to inialize job queue: $err.msg()') util.exit_with_message(1, 'Failed to inialize job queue: $err.msg()')

View File

@ -148,6 +148,7 @@ pub fn (ctx &Context) is_authenticated() bool {
return false return false
} }
// body sends the given body as an HTTP response.
pub fn (mut ctx Context) body(status http.Status, content_type string, body string) Result { pub fn (mut ctx Context) body(status http.Status, content_type string, body string) Result {
ctx.status = status ctx.status = status
ctx.content_type = content_type ctx.content_type = content_type
@ -334,11 +335,13 @@ fn handle_conn<T>(mut conn net.TcpConn, mut app T, routes map[string]Route) {
labels := [ labels := [
['method', app.req.method.str()]!, ['method', app.req.method.str()]!,
['path', app.req.url]!, ['path', app.req.url]!,
['status', app.status.int().str()]! ['status', app.status.int().str()]!,
] ]
app.collector.counter_increment(name: 'http_requests_total', labels: labels) app.collector.counter_increment(name: 'http_requests_total', labels: labels)
app.collector.histogram_record(time.ticks() - app.page_gen_start, name: 'http_requests_time_ms', labels: labels) app.collector.histogram_record(time.ticks() - app.page_gen_start,
/* app.collector.histogram_ */ name: 'http_requests_time_ms'
labels: labels
)
unsafe { unsafe {
free(app) free(app)

View File

@ -13,3 +13,4 @@ api_update_frequency = 2
image_rebuild_frequency = 1 image_rebuild_frequency = 1
max_concurrent_builds = 3 max_concurrent_builds = 3
max_log_age = 64 max_log_age = 64
collect_metrics = true