Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: feat(metrics): add actix-web metrics exporter #793

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ actix-cors = "0.6"
actix-http = "3"
actix-rt = "2"
actix-web = "4"
actix-web-prom = "0.6.0"
anyhow = "1.0"
async-trait = "0.1"
brotli = "3"
Expand Down
1 change: 1 addition & 0 deletions martin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ spreet.workspace = true
subst.workspace = true
thiserror.workspace = true
tilejson.workspace = true
actix-web-prom.workspace = true
tokio = { workspace = true, features = ["io-std"] }

# Optional dependencies for ssl support
Expand Down
18 changes: 18 additions & 0 deletions martin/src/srv/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ use crate::srv::config::{SrvConfig, KEEP_ALIVE_DEFAULT, LISTEN_ADDRESSES_DEFAULT
use crate::utils::{decode_brotli, decode_gzip, encode_brotli, encode_gzip};
use crate::Error::BindingError;

use actix_web_prom::PrometheusMetricsBuilder;
use std::collections::HashMap;

/// List of keywords that cannot be used as source IDs. Some of these are reserved for future use.
/// Reserved keywords must never end in a "dot number" (e.g. ".1")
pub const RESERVED_KEYWORDS: &[&str] = &[
Expand Down Expand Up @@ -257,6 +260,9 @@ fn merge_tilejson(sources: Vec<&dyn Source>, tiles_url: String) -> TileJSON {
result
}

// TODO: Change here, to add an attribute to tell actix-web-prom that we want to keep the
// cardinality of {source_ids}

#[route("/{source_ids}/{z}/{x}/{y}", method = "GET", method = "HEAD")]
async fn get_tile(
req: HttpRequest,
Expand Down Expand Up @@ -407,6 +413,17 @@ pub fn router(cfg: &mut web::ServiceConfig) {

/// Create a new initialized Actix `App` instance together with the listening address.
pub fn new_server(config: SrvConfig, all_sources: AllSources) -> crate::Result<(Server, String)> {
// metrics setup
let labels = HashMap::new();

// labels.insert("label_foo".to_string(), "value_barbarbbabbmiles".to_string());
let prometheus = PrometheusMetricsBuilder::new("martin")
.endpoint("/metrics")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we start handling /metrics, we would have to declare this as a reserved keyword (we might be missing docs in a martin book for this). One workaround perhaps would be to add everything "magical" to the /_/metrics style prefixes because _ is not a valid source ID i think.

/// List of keywords that cannot be used as source IDs. Some of these are reserved for future use.
/// Reserved keywords must never end in a "dot number" (e.g. ".1")
pub const RESERVED_KEYWORDS: &[&str] = &[
"catalog", "config", "font", "health", "help", "index", "manifest", "refresh", "reload",
"sprite", "status",
];

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we start handling /metrics, we would have to declare this as a reserved keyword (we might be missing docs in a martin book for this). One workaround perhaps would be to add everything "magical" to the /_/metrics style prefixes because _ is not a valid source ID i think.

/// List of keywords that cannot be used as source IDs. Some of these are reserved for future use.
/// Reserved keywords must never end in a "dot number" (e.g. ".1")
pub const RESERVED_KEYWORDS: &[&str] = &[
"catalog", "config", "font", "health", "help", "index", "manifest", "refresh", "reload",
"sprite", "status",
];

Right, as you wish, I'm fine with both solutions (the reserved keyword and the /_/metrics workaround). We just have to keep in mind that /metrics is the standard path and the default, so the second solution would mean a little bit more config on the scraper side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point about conventions (actually, didn't we talk about it elsewhere?), i'm ok to add /metrics to reserved then

.const_labels(labels)
.build()
.unwrap();
// end of metrics setup

let keep_alive = Duration::from_secs(config.keep_alive.unwrap_or(KEEP_ALIVE_DEFAULT));
let worker_processes = config.worker_processes.unwrap_or_else(num_cpus::get);
let listen_addresses = config
Expand All @@ -424,6 +441,7 @@ pub fn new_server(config: SrvConfig, all_sources: AllSources) -> crate::Result<(
.wrap(cors_middleware)
.wrap(middleware::NormalizePath::new(TrailingSlash::MergeOnly))
.wrap(middleware::Logger::default())
.wrap(prometheus.clone())
.configure(router)
})
.bind(listen_addresses.clone())
Expand Down