cloudflare / cloudflare/pingora

Prometheus not show any values in http://localhost:1234/metrics

Open
#636 14 comments 1 reaction 1 assignee Claimed by @johnhurt View on GitHub
documentation
Dominant language
Rust
Stars
27.4k
Forks
1.7k
Avg merge
6h 22m
Merged PRs (30d)
3

Description

This is my Pingora server code and I added Prometheus but I can not see any values using http://localhost:1234/metrics URL. How to solve this issue? I can see "my_counter" value increasing by `println!("my_counter: {}", MY_COUNTER.get());` code. But nothing show in metrics.

I check Prometheus server run or not,

```Bash
ss -tuln | grep 1234
tcp LISTEN 0 4096 0.0.0.0:1234 0.0.0.0:*
```

This is my code:

```Rust
use async_trait::async_trait;
use clap::Parser;
use log::info;
use once_cell::sync::Lazy;
use pingora_core::Result;
use pingora_core::listeners::tls::TlsSettings;
use pingora_core::server::Server;
use pingora_core::server::configuration::Opt;
use pingora_core::services::background::background_service;
use pingora_core::services::listening::Service;
use pingora_core::upstreams::peer::HttpPeer;
use pingora_load_balancing::{LoadBalancer, health_check, selection::RoundRobin};
use pingora_proxy::http_proxy_service;
use pingora_proxy::{ProxyHttp, Session};
use prometheus::{IntCounter, register_int_counter};
use std::{sync::Arc, time::Duration};

pub struct LB(Arc>); // Load Balancer with Round Robin selection

static MY_COUNTER: Lazy =
Lazy::new(|| register_int_counter!("my_counter", "my counter").unwrap());

// Create Load Balance Proxy
#[async_trait]
impl ProxyHttp for LB {
// For this small example, we don't need context storage
type CTX = ();
fn new_ctx(&self) -> Self::CTX {}

// Upstream_peer returns the address where the request should be proxied to.
async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result> {
let upstream = self
.0
.select(b"", 256) // hash doesn't matter
.unwrap(); // use the select() method for the LoadBalancer to round-robin across the upstream IPs.

info!("upstream peer is: {:?}", upstream);

// Set SNI to one.one.one.one
let peer = Box::new(HttpPeer::new(
upstream,
false,
"one.one.one.one".to_string(),
)); // Set SNI to one.one.one.one and disable TLS (HTTP) with flase / enable TLS (HTTPS) with true
Ok(peer)
}

// In order for the 1.1.1.1 backends to accept our requests, a host header must be present.
// Adding this header can be done by the upstream_request_filter() callback which modifies the
// request header after the connection to the backends are established and before the request header is sent.
async fn upstream_request_filter(
&self,
_session: &mut Session,
upstream_request: &mut pingora_http::RequestHeader,
_ctx: &mut Self::CTX,
) -> Result<()> {
upstream_request
.insert_header("Host", "one.one.one.one")
.unwrap();
Ok(())
}

async fn logging(
&self,
session: &mut Session,
_e: Option<&pingora_core::Error>,
ctx: &mut Self::CTX,
) {
let response_code = session
.response_written()
.map_or(0, |resp| resp.status.as_u16());
info!(
"{} response code: {response_code}",
self.request_summary(session, ctx)
);

MY_COUNTER.inc();
println!("my_counter: {}", MY_COUNTER.get());
}
}
// RUST_LOG=INFO cargo run --example load_balancer
fn main() {
env_logger::init();

MY_COUNTER.inc();
println!("my_counter: {}", MY_COUNTER.get());

let opt = Opt::parse_args(); // read command line arguments, so cargo run -- -h command "-- -h" to see help
let mut my_server = Server::new(Some(opt)).unwrap(); // create server with command line arguments
my_server.bootstrap();

// All list of array upstreams servers to load balance
let mut upstreams = LoadBalancer::try_from_iter(["127.0.0.1:3000"]).unwrap();

// ===================
// Health Check
// ===================

// We add health check in the background so that the bad server is never selected.
let hc = health_check::TcpHealthCheck::new();
upstreams.set_health_check(hc);
upstreams.health_check_frequency = Some(Duration::from_secs(1));

let background = background_service("health check", upstreams);

let upstreams = background.task();

// ===================
// Load Balance Proxy
// ===================

let mut lb = http_proxy_service(&my_server.configuration, LB(upstreams));
lb.add_tcp("0.0.0.0:6188");

// ===================
// TLS with H2 enabled to load balance proxy
// ===================

let cert_path = format!("{}/certs/cert.pem", env!("CARGO_MANIFEST_DIR"));
let key_path = format!("{}/certs/key.pem", env!("CARGO_MANIFEST_DIR"));

let mut tls_settings = TlsSettings::intermediate(&cert_path, &key_path).unwrap();
tls_settings.enable_h2(); // This work HTTP/2.0 and HTTP/1.1 (Check it)
lb.add_tls_with_settings("0.0.0.0:6189", None, tls_settings);

// ===================
// Prometheus HTTP Service
// ===================

let mut prometheus_service_http = Service::prometheus_http_service();
prometheus_service_http.add_tcp("0.0.0.0:1234");

// ===================
// Run Server
// ===================

my_server.add_service(prometheus_service_http); // add prometheus http service to server
my_server.add_service(lb); // add load balance proxy to server
my_server.add_service(background); // add health check to server
my_server.run_forever(); // spawn all the runtime threads and block the main thread until the server is ready to exit.
}
```

This is my Toml file:

```Toml
[package]
name = "test_pingora"
version = "0.1.0"
edition = "2024"

[dependencies]
axum = { version = "0.8.4", optional = true }
tokio = { version = "1.44.2", features = ["full"], optional = true }

# pingora = "0.5.0"
pingora-core = { version = "0.5.0", features = ["rustls"], optional = true }
pingora-proxy = { version = "0.5.0", optional = true }
pingora-load-balancing = { version = "0.5.0", optional = true }
pingora-http = { version = "0.5.0", optional = true }
async-trait = { version = "0.1.52", optional = true }
log = { version = "0.4.17", optional = true }
env_logger = { version = "0.11.8", optional = true }
clap = { version = "4.5.39", features = ["derive"] }
prometheus = { version = "0.14.0", optional = true }
once_cell = "1.21.3"

[features]
server = ["axum", "tokio"]
proxy = [
"pingora-proxy",
"pingora-http",
"pingora-load-balancing",
"async-trait",
"log",
"env_logger",
"pingora-core",
"prometheus",
]

[[bin]]
name = "server"
path = "src/server.rs"
required-features = ["server"]

[[bin]]
name = "proxy"
path = "src/proxy.rs"
required-features = ["proxy"]
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.