Skip to content

Commit a794583

Browse files
committed
advanced tracing
1 parent f2375d1 commit a794583

File tree

11 files changed

+251
-106
lines changed

11 files changed

+251
-106
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ repository = "https://github.com/conblem/acme-dns-rust/"
1010
description = "Acme DNS implementation written in Rust"
1111

1212
[dependencies]
13+
prometheus = "0.10"
1314
tracing = "0.1"
1415
tracing-subscriber = "0.2"
1516
tracing-futures = { version = "0.2.4", features = ["futures-03"]}

src/acme.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use tokio::runtime::Handle;
55
use tokio::stream::StreamExt;
66

77
use crate::util::{error, to_i64};
8+
use tracing_futures::Instrument;
89

910
#[derive(Clone)]
1011
pub struct DatabasePersist {
@@ -30,6 +31,7 @@ fn persist_kind(kind: &PersistKind) -> &str {
3031
}
3132

3233
impl Persist for DatabasePersist {
34+
#[tracing::instrument(name = "DatabasePersist::put", err, skip(self))]
3335
fn put<'a>(&self, key: &PersistKey<'a>, value: &[u8]) -> acme_lib::Result<()> {
3436
let PersistKey { realm, kind, key } = key;
3537

@@ -44,6 +46,7 @@ impl Persist for DatabasePersist {
4446
self.handle.block_on(query).map(|_| ()).map_err(error)
4547
}
4648

49+
#[tracing::instrument(name = "DatabasePersist::get", err, skip(self))]
4750
fn get<'a>(&self, key: &PersistKey<'a>) -> acme_lib::Result<Option<Vec<u8>>> {
4851
let PersistKey { realm, kind, key } = key;
4952

@@ -54,7 +57,7 @@ impl Persist for DatabasePersist {
5457
.bind(persist_kind(kind))
5558
.fetch(&self.pool);
5659

57-
match self.handle.block_on(rows.try_next()) {
60+
match self.handle.block_on(rows.try_next().in_current_span()) {
5861
Ok(Some(row)) => row.try_get("value").map_err(error),
5962
Ok(None) => Ok(None),
6063
Err(e) => Err(error(e)),

src/api.rs

Lines changed: 88 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
use anyhow::{anyhow, Error, Result};
22
use futures_util::future::OptionFuture;
3-
use futures_util::stream::{repeat, TryStream};
3+
use futures_util::stream::{repeat, Stream};
44
use futures_util::FutureExt;
55
use futures_util::{StreamExt, TryStreamExt};
66
use parking_lot::RwLock;
7+
use prometheus::proto::MetricFamily;
8+
use prometheus::{Encoder, TextEncoder};
79
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
810
use rustls::{NoClientAuth, ServerConfig};
911
use sqlx::PgPool;
1012
use std::sync::Arc;
1113
use tokio::io::{AsyncRead, AsyncWrite};
1214
use tokio::net::{TcpListener, ToSocketAddrs};
1315
use tokio_rustls::TlsAcceptor;
14-
use tracing::{error, info};
16+
use tracing::{debug_span, error, info};
1517
use tracing_futures::Instrument;
16-
use warp::{http::Response, reply, serve, Filter, Rejection, Reply};
18+
use warp::{http::Response, serve, Filter, Rejection, Reply};
1719

1820
use crate::cert::{Cert, CertFacade};
1921
use crate::domain::{Domain, DomainFacade};
22+
use crate::util::to_u64;
2023

2124
struct Acceptor {
2225
pool: PgPool,
@@ -56,12 +59,16 @@ impl Acceptor {
5659
}
5760

5861
async fn load_cert(&self) -> Result<TlsAcceptor> {
59-
let new_cert = CertFacade::first_cert(&self.pool).await;
62+
let new_cert = CertFacade::first_cert(&self.pool).in_current_span().await;
6063

6164
let db_cert = match (new_cert, &*self.config.read()) {
6265
(Ok(Some(new_cert)), (cert, _)) if Some(&new_cert) != cert.as_ref() => new_cert,
63-
(_, (_, server_config)) => return Ok(TlsAcceptor::from(Arc::clone(server_config))),
66+
(_, (_, server_config)) => {
67+
info!("Using existing TLS Config");
68+
return Ok(TlsAcceptor::from(Arc::clone(server_config)));
69+
}
6470
};
71+
info!(timestamp = to_u64(&db_cert.update), "Found new cert");
6572

6673
let server_config = match Acceptor::create_server_config(&db_cert) {
6774
Ok(server_config) => server_config,
@@ -73,48 +80,50 @@ impl Acceptor {
7380
};
7481

7582
*self.config.write() = (Some(db_cert), Arc::clone(&server_config));
83+
info!("Created new TLS config");
7684
Ok(TlsAcceptor::from(server_config))
7785
}
7886
}
7987

8088
fn stream(
8189
listener: TcpListener,
8290
pool: PgPool,
83-
) -> impl TryStream<Ok = impl AsyncRead + AsyncWrite + Send + Unpin + 'static, Error = Error> + Send
91+
) -> impl Stream<Item = Result<impl AsyncRead + AsyncWrite + Send + Unpin + 'static, Error>> + Send
8492
{
8593
let acceptor = Acceptor::new(pool);
8694

8795
listener
8896
.zip(repeat(acceptor))
8997
.map(|(conn, acceptor)| conn.map(|c| (c, acceptor)))
9098
.err_into()
91-
.map_ok(|(conn, acceptor)| async move {
92-
let tls = acceptor.load_cert().await?;
93-
Ok(tls.accept(conn).await?)
99+
.map_ok(|(conn, acceptor)| {
100+
let addr = conn.peer_addr();
101+
async move {
102+
let tls = acceptor.load_cert().in_current_span().await?;
103+
Ok(tls.accept(conn).in_current_span().await?)
104+
}
105+
.instrument(debug_span!("TLS", remote.addr = ?addr))
94106
})
95107
.try_buffer_unordered(100)
96108
.inspect_err(|err| error!("Stream error: {:?}", err))
97109
.filter(|stream| futures_util::future::ready(stream.is_ok()))
110+
.into_stream()
98111
}
99112

100113
pub struct Api {
101114
http: Option<TcpListener>,
102115
https: Option<TcpListener>,
116+
prom: Option<TcpListener>,
103117
pool: PgPool,
104118
}
105119

106-
#[tracing::instrument(skip(pool))]
107-
async fn register(pool: PgPool, domain: Domain) -> Result<reply::Response, Rejection> {
108-
let _domain = match DomainFacade::create_domain(&pool, &domain)
109-
.in_current_span()
110-
.await
111-
{
120+
async fn register(pool: PgPool, domain: Domain) -> Result<impl Reply, Rejection> {
121+
let _domain = match DomainFacade::create_domain(&pool, &domain).await {
112122
Err(e) => {
113123
error!("{}", e);
114124
return Ok(Response::builder()
115125
.status(500)
116126
.body(e.to_string())
117-
.unwrap()
118127
.into_response());
119128
}
120129
Ok(domain) => domain,
@@ -124,36 +133,67 @@ async fn register(pool: PgPool, domain: Domain) -> Result<reply::Response, Rejec
124133
Ok(Response::new("no error").into_response())
125134
}
126135

136+
fn prom() -> impl Reply {
137+
let encoder = TextEncoder::new();
138+
let family = MetricFamily::new();
139+
let mut res = vec![];
140+
if let Err(e) = encoder.encode(&[family], &mut res) {
141+
error!("{}", e);
142+
return Response::builder()
143+
.status(500)
144+
.body(e.to_string())
145+
.into_response();
146+
}
147+
148+
Response::builder()
149+
.header("Content-Type", "text/plain")
150+
.body(res)
151+
.into_response()
152+
}
153+
127154
impl Api {
128155
pub async fn new<A: ToSocketAddrs>(
129156
http: Option<A>,
130157
https: Option<A>,
158+
prom: Option<A>,
131159
pool: PgPool,
132160
) -> Result<Self> {
133161
let http = OptionFuture::from(http.map(TcpListener::bind)).map(Option::transpose);
134162
let https = OptionFuture::from(https.map(TcpListener::bind)).map(Option::transpose);
163+
let prom = OptionFuture::from(prom.map(TcpListener::bind)).map(Option::transpose);
135164

136-
let (http, https) = tokio::try_join!(http, https)?;
165+
let (http, https, prom) = tokio::try_join!(http, https, prom)?;
137166

138-
Ok(Api { http, https, pool })
167+
Ok(Api {
168+
http,
169+
https,
170+
prom,
171+
pool,
172+
})
139173
}
140174

141-
#[tracing::instrument(skip(self))]
175+
#[tracing::instrument(name = "Api::spawn", skip(self))]
142176
pub async fn spawn(self) -> Result<()> {
143177
info!("Starting API spawn");
178+
let metrics = warp::path("metrics")
179+
.and(warp::get())
180+
.map(prom)
181+
.with(warp::trace::request());
144182

145183
let pool = self.pool.clone();
146184
let routes = warp::path("register")
147185
.and(warp::post())
148186
.map(move || pool.clone())
149187
.and(warp::body::json())
150-
.and_then(register);
188+
.and_then(register)
189+
.with(warp::trace::request());
151190

152191
let http = self
153192
.http
154193
.map(|http| {
155-
info!(?http, "Starting http");
156-
http.in_current_span()
194+
//info!(?http, "Starting http");
195+
let addr = http.local_addr();
196+
http.instrument(debug_span!("HTTP", local.addr = ?addr))
157197
})
158198
.map(|http| serve(routes.clone()).serve_incoming(http))
159199
.map(tokio::spawn);
@@ -162,17 +202,36 @@ impl Api {
162202
let https = self
163203
.https
164204
.map(|https| {
165-
info!(?https, "Starting https");
166-
stream(https, pool).into_stream().in_current_span()
205+
//info!(?https, "Starting https");
206+
let addr = https.local_addr();
207+
stream(https, pool).instrument(debug_span!("HTTPS", local.addr = ?addr))
167208
})
168209
.map(|https| serve(routes).serve_incoming(https))
169210
.map(tokio::spawn);
170211

171-
match (https, http) {
172-
(Some(https), Some(http)) => tokio::try_join!(https, http).map(|_| ()),
173-
(Some(https), None) => https.await,
174-
(None, Some(http)) => http.await,
175-
_ => Ok(()),
212+
let prom = self
213+
.prom
214+
.map(|prom| {
215+
//info!(?http, "Starting http");
216+
let addr = prom.local_addr();
217+
prom.instrument(debug_span!("PROM", local.addr = ?addr))
218+
})
219+
.map(|prom| serve(metrics).serve_incoming(prom))
220+
.map(tokio::spawn);
221+
222+
match (https, http, prom) {
223+
(Some(https), Some(http), Some(prom)) => {
224+
tokio::try_join!(https, http, prom).map(|_| ())
225+
}
226+
(None, None, None) => Ok(()),
227+
228+
(Some(https), Some(http), None) => tokio::try_join!(https, http).map(|_| ()),
229+
(Some(https), None, Some(prom)) => tokio::try_join!(https, prom).map(|_| ()),
230+
(None, Some(http), Some(prom)) => tokio::try_join!(http, prom).map(|_| ()),
231+
232+
(Some(https), None, None) => https.await,
233+
(None, Some(http), None) => http.await,
234+
(None, None, Some(prom)) => prom.await,
176235
}?;
177236

178237
Ok(())

src/cert.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use anyhow::{anyhow, Context, Result};
33
use sqlx::{Executor, FromRow, PgPool, Postgres};
44
use std::time::Duration;
55
use tokio::time::Interval;
6-
use tracing::{error, info};
6+
use tracing::{error, info, Span};
7+
use tracing_futures::Instrument;
78
use uuid::Uuid;
89

910
use crate::acme::DatabasePersist;
@@ -155,8 +156,11 @@ pub struct CertManager {
155156
}
156157

157158
impl CertManager {
159+
#[tracing::instrument(name = "CertManager::new", skip(pool, persist))]
158160
pub async fn new(pool: PgPool, persist: DatabasePersist, acme: String) -> Result<Self> {
161+
let span = Span::current();
159162
let directory = tokio::task::spawn_blocking(move || {
163+
let _enter = span.enter();
160164
Directory::from_url(persist, DirectoryUrl::Other(&acme))
161165
})
162166
.await??;
@@ -167,24 +171,30 @@ impl CertManager {
167171
// maybe useless function
168172
fn interval() -> Interval {
169173
// use constant
170-
tokio::time::interval(Duration::from_secs(3600))
174+
tokio::time::interval(Duration::from_secs(HOUR))
171175
}
172176

177+
#[tracing::instrument(name = "CertManager::spawn", skip(self))]
173178
pub async fn spawn(self) -> Result<()> {
174-
tokio::spawn(async move {
175-
let mut interval = CertManager::interval();
176-
loop {
177-
interval.tick().await;
178-
if true {
179-
continue;
179+
tokio::spawn(
180+
async move {
181+
let mut interval = CertManager::interval();
182+
loop {
183+
interval.tick().await;
184+
info!("Started Interval");
185+
if true {
186+
info!("Skipping Interval");
187+
continue;
188+
}
189+
if let Err(e) = self.test().await {
190+
error!("{}", e);
191+
continue;
192+
}
193+
info!("Interval successfully passed");
180194
}
181-
if let Err(e) = self.test().await {
182-
error!("{}", e);
183-
continue;
184-
}
185-
info!("Interval successfully passed");
186195
}
187-
})
196+
.in_current_span(),
197+
)
188198
.await?;
189199

190200
Ok(())

src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use tracing::{debug, info, info_span};
99
pub struct Api {
1010
pub http: Option<String>,
1111
pub https: Option<String>,
12+
pub prom: Option<String>,
1213
}
1314

1415
fn default_acme() -> String {

0 commit comments

Comments
 (0)