Skip to content

Commit a5cfe5d

Browse files
committed
doc: comment the code
Signed-off-by: Jeremie Drouet <jeremie.drouet@gmail.com>
1 parent a4b49b0 commit a5cfe5d

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/lib.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub mod postgres;
1616
#[cfg(feature = "sqlite")]
1717
pub mod sqlite;
1818

19+
/// Attributes describing the database connection and context.
20+
/// Used for span enrichment and attribute propagation.
1921
#[derive(Debug, Default)]
2022
struct Attributes {
2123
name: Option<String>,
@@ -24,13 +26,18 @@ struct Attributes {
2426
database: Option<String>,
2527
}
2628

29+
/// Builder for constructing a [`Pool`] with custom attributes.
30+
///
31+
/// Allows setting database name, host, port, and other identifying information
32+
/// for tracing purposes.
2733
#[derive(Debug)]
2834
pub struct PoolBuilder<DB: sqlx::Database> {
2935
pool: sqlx::Pool<DB>,
3036
attributes: Attributes,
3137
}
3238

3339
impl<DB: sqlx::Database> PoolBuilder<DB> {
40+
/// Create a new builder from an existing SQLx pool.
3441
pub fn new(pool: sqlx::Pool<DB>) -> Self {
3542
let url = pool.connect_options().to_url_lossy();
3643
let attributes = Attributes {
@@ -44,26 +51,31 @@ impl<DB: sqlx::Database> PoolBuilder<DB> {
4451
Self { pool, attributes }
4552
}
4653

54+
/// Set a custom name for the pool (for peer.service attribute).
4755
pub fn with_name(mut self, name: impl Into<String>) -> Self {
4856
self.attributes.name = Some(name.into());
4957
self
5058
}
5159

60+
/// Set the database name attribute.
5261
pub fn with_database(mut self, database: impl Into<String>) -> Self {
5362
self.attributes.database = Some(database.into());
5463
self
5564
}
5665

66+
/// Set the host attribute.
5767
pub fn with_host(mut self, host: impl Into<String>) -> Self {
5868
self.attributes.host = Some(host.into());
5969
self
6070
}
6171

72+
/// Set the port attribute.
6273
pub fn with_port(mut self, port: u16) -> Self {
6374
self.attributes.port = Some(port);
6475
self
6576
}
6677

78+
/// Build the [`Pool`] with the configured attributes.
6779
pub fn build(self) -> Pool<DB> {
6880
Pool {
6981
inner: self.pool,
@@ -72,7 +84,9 @@ impl<DB: sqlx::Database> PoolBuilder<DB> {
7284
}
7385
}
7486

75-
/// An asynchronous pool of SQLx database connections.
87+
/// An asynchronous pool of SQLx database connections with tracing instrumentation.
88+
///
89+
/// Wraps a SQLx [`Pool`] and propagates tracing attributes to all acquired connections.
7690
#[derive(Clone, Debug)]
7791
pub struct Pool<DB>
7892
where
@@ -86,6 +100,7 @@ impl<DB> From<sqlx::Pool<DB>> for Pool<DB>
86100
where
87101
DB: sqlx::Database,
88102
{
103+
/// Convert a SQLx [`Pool`] into a tracing-instrumented [`Pool`].
89104
fn from(inner: sqlx::Pool<DB>) -> Self {
90105
PoolBuilder::new(inner).build()
91106
}
@@ -96,14 +111,16 @@ where
96111
DB: sqlx::Database,
97112
{
98113
/// Retrieves a connection and immediately begins a new transaction.
114+
///
115+
/// The returned [`Transaction`] is instrumented for tracing.
99116
pub async fn begin<'c>(&'c self) -> Result<Transaction<'c, DB>, sqlx::Error> {
100117
self.inner.begin().await.map(|inner| Transaction {
101118
inner,
102119
attributes: self.attributes.clone(),
103120
})
104121
}
105122

106-
/// Retrieves a connection and immediately begins a new transaction.
123+
/// Acquires a pooled connection, instrumented for tracing.
107124
pub async fn acquire(&self) -> Result<PoolConnection<DB>, sqlx::Error> {
108125
self.inner.acquire().await.map(|inner| PoolConnection {
109126
attributes: self.attributes.clone(),
@@ -112,6 +129,9 @@ where
112129
}
113130
}
114131

132+
/// Wrapper for a mutable SQLx connection reference with tracing attributes.
133+
///
134+
/// Used internally for transaction and pool connection executors.
115135
pub struct Connection<'c, DB>
116136
where
117137
DB: sqlx::Database,
@@ -126,6 +146,9 @@ impl<'c, DB: sqlx::Database> std::fmt::Debug for Connection<'c, DB> {
126146
}
127147
}
128148

149+
/// A pooled SQLx connection instrumented for tracing.
150+
///
151+
/// Implements [`sqlx::Executor`] and propagates tracing attributes.
129152
#[derive(Debug)]
130153
pub struct PoolConnection<DB>
131154
where
@@ -135,7 +158,9 @@ where
135158
attributes: Arc<Attributes>,
136159
}
137160

138-
/// An in-progress database transaction or savepoint.
161+
/// An in-progress database transaction or savepoint, instrumented for tracing.
162+
///
163+
/// Wraps a SQLx [`Transaction`] and propagates tracing attributes.
139164
#[derive(Debug)]
140165
pub struct Transaction<'c, DB>
141166
where

src/span.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,57 @@
1+
/// Macro to create a tracing span for a SQLx operation with OpenTelemetry-compatible fields.
2+
///
3+
/// - `$name`: The operation name (e.g., "sqlx.execute").
4+
/// - `$statement`: The SQL statement being executed.
5+
/// - `$attributes`: Connection or pool attributes for peer and db context.
6+
///
7+
/// This macro is used internally by the crate to instrument all major SQLx operations.
18
#[macro_export]
29
macro_rules! instrument {
310
($name:expr, $statement:expr, $attributes:expr) => {
411
tracing::info_span!(
512
$name,
13+
// Database name (if available)
614
"db.name" = $attributes.database,
15+
// Operation type (filled by SQLx or left empty)
716
"db.operation" = ::tracing::field::Empty,
17+
// The SQL query text
818
"db.query.text" = $statement,
19+
// Number of affected rows (to be filled after execution)
920
"db.response.affected_rows" = ::tracing::field::Empty,
21+
// Number of returned rows (to be filled after execution)
1022
"db.response.returned_rows" = ::tracing::field::Empty,
23+
// Status code of the response (to be filled after execution)
1124
"db.response.status_code" = ::tracing::field::Empty,
25+
// Table name (optional, left empty)
1226
"db.sql.table" = ::tracing::field::Empty,
27+
// Database system (e.g., "postgresql", "sqlite")
1328
"db.system.name" = DB::SYSTEM,
29+
// Error type, message, and stacktrace (to be filled on error)
1430
"error.type" = ::tracing::field::Empty,
1531
"error.message" = ::tracing::field::Empty,
1632
"error.stacktrace" = ::tracing::field::Empty,
33+
// Peer (server) host and port
1734
"net.peer.name" = $attributes.host,
1835
"net.peer.port" = $attributes.port,
36+
// OpenTelemetry semantic fields
1937
"otel.kind" = "client",
2038
"otel.status_code" = ::tracing::field::Empty,
2139
"otel.status_description" = ::tracing::field::Empty,
40+
// Peer service name (if set)
2241
"peer.service" = $attributes.name,
2342
)
2443
};
2544
}
2645

46+
/// Records that a single row was returned in the current tracing span.
47+
/// Used for fetch_one operations.
2748
pub fn record_one<T>(_value: &T) {
2849
let span = tracing::Span::current();
2950
span.record("db.response.returned_rows", 1);
3051
}
3152

53+
/// Records whether an optional row was returned in the current tracing span.
54+
/// Used for fetch_optional operations.
3255
pub fn record_optional<T>(value: &Option<T>) {
3356
let span = tracing::Span::current();
3457
span.record(
@@ -37,10 +60,14 @@ pub fn record_optional<T>(value: &Option<T>) {
3760
);
3861
}
3962

63+
/// Records error details in the current tracing span for a SQLx error.
64+
/// Sets OpenTelemetry status and error fields for observability backends.
4065
pub fn record_error(err: &sqlx::Error) {
4166
let span = tracing::Span::current();
67+
// Mark the span as an error for OpenTelemetry
4268
span.record("otel.status_code", "error");
4369
span.record("otel.status_description", err.to_string());
70+
// Classify error type as client or server
4471
match err {
4572
sqlx::Error::ColumnIndexOutOfBounds { .. }
4673
| sqlx::Error::ColumnDecode { .. }
@@ -55,6 +82,7 @@ pub fn record_error(err: &sqlx::Error) {
5582
span.record("error.type", "server");
5683
}
5784
}
85+
// Attach error message and stacktrace for debugging
5886
span.record("error.message", err.to_string());
5987
span.record("error.stacktrace", format!("{err:?}"));
6088
}

src/transaction.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ where
66
DB: crate::prelude::Database + sqlx::Database,
77
for<'a> &'a mut DB::Connection: sqlx::Executor<'a, Database = DB>,
88
{
9+
/// Returns a tracing-instrumented executor for this transaction.
10+
///
11+
/// This allows running queries with full span context and attributes.
912
pub fn executor(&mut self) -> crate::Connection<'_, DB> {
1013
crate::Connection {
1114
inner: &mut *self.inner,
@@ -14,6 +17,10 @@ where
1417
}
1518
}
1619

20+
/// Implements `sqlx::Executor` for a mutable reference to a tracing-instrumented transaction.
21+
///
22+
/// Each method creates a tracing span for the SQL operation, attaches relevant attributes,
23+
/// and records errors or row counts as appropriate for observability.
1724
impl<'c, DB> sqlx::Executor<'c> for &'c mut crate::Transaction<'c, DB>
1825
where
1926
DB: crate::prelude::Database + sqlx::Database,

0 commit comments

Comments
 (0)