Skip to content

Commit 870f23c

Browse files
authored
Merge pull request #87 from tankyleo/26-01-logging
Add logger for VSS
2 parents d53134d + 52fd919 commit 870f23c

13 files changed

Lines changed: 391 additions & 42 deletions

File tree

.github/workflows/build-and-deploy-rust.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ jobs:
3838
- name: Build and Deploy VSS Server
3939
run: |
4040
cd rust
41-
cargo build
42-
cargo run server/vss-server-config.toml&
41+
RUSTFLAGS="--cfg noop_authorizer" cargo build --no-default-features
42+
./target/debug/vss-server server/vss-server-config.toml&
4343
4444
- name: Hit endpoint to verify service is up
4545
run: |
4646
sleep 5
4747
4848
# Put request with store='storeId' and key=k1
4949
hex=0A0773746F726549641A150A026B3110FFFFFFFFFFFFFFFFFF011A046B317631
50-
curl --data-binary "$(echo "$hex" | xxd -r -p)" http://localhost:8080/vss/putObjects
50+
curl -f --data-binary "$(echo "$hex" | xxd -r -p)" http://localhost:8080/vss/putObjects
5151
5252
# Get request with store='storeId' and key=k1
5353
hex=0A0773746F7265496412026B31
54-
curl --data-binary "$(echo "$hex" | xxd -r -p)" http://localhost:8080/vss/getObject
54+
curl -f --data-binary "$(echo "$hex" | xxd -r -p)" http://localhost:8080/vss/getObject

.github/workflows/ldk-node-integration.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ jobs:
4444
- name: Build and Deploy VSS Server
4545
run: |
4646
cd vss-server/rust
47-
cargo build
48-
cargo run --no-default-features server/vss-server-config.toml&
47+
RUSTFLAGS="--cfg noop_authorizer" cargo build --no-default-features
48+
./target/debug/vss-server server/vss-server-config.toml&
4949
- name: Run LDK Node Integration tests
5050
run: |
5151
cd ldk-node

rust/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ lto = true
1313

1414
[profile.dev]
1515
panic = "abort"
16+
17+
[workspace.lints.rust.unexpected_cfgs]
18+
level = "forbid"
19+
check-cfg = ['cfg(noop_authorizer)']

rust/api/src/auth.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::error::VssError;
22
use async_trait::async_trait;
33
use std::collections::HashMap;
4-
use std::string::ToString;
54

65
/// Response returned for [`Authorizer`] request if user is authenticated and authorized.
76
#[derive(Debug, Clone)]
@@ -21,10 +20,13 @@ pub trait Authorizer: Send + Sync {
2120
}
2221

2322
/// A no-operation authorizer, which lets any user-request go through.
23+
#[cfg(feature = "_test_utils")]
2424
pub struct NoopAuthorizer {}
2525

26+
#[cfg(feature = "_test_utils")]
2627
const UNAUTHENTICATED_USER: &str = "unauth-user";
2728

29+
#[cfg(feature = "_test_utils")]
2830
#[async_trait]
2931
impl Authorizer for NoopAuthorizer {
3032
async fn verify(

rust/impls/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ bytes = "1.4.0"
1313
tokio = { version = "1.38.0", default-features = false, features = ["rt", "macros"] }
1414
native-tls = { version = "0.2.14", default-features = false }
1515
postgres-native-tls = { version = "0.5.2", default-features = false, features = ["runtime"] }
16+
log = { version = "0.4.29", default-features = false }
1617

1718
[dev-dependencies]
1819
tokio = { version = "1.38.0", default-features = false, features = ["rt-multi-thread", "macros"] }

rust/impls/src/postgres_store.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use tokio::sync::Mutex;
1717
use tokio_postgres::tls::{MakeTlsConnect, TlsConnect};
1818
use tokio_postgres::{error, Client, NoTls, Socket, Transaction};
1919

20+
use log::{debug, info, warn};
21+
2022
pub use native_tls::Certificate;
2123

2224
pub(crate) struct VssDbRecord {
@@ -104,6 +106,7 @@ where
104106

105107
async fn ensure_connected(&self, client: &mut Client) -> Result<(), Error> {
106108
if client.is_closed() || client.check_connection().await.is_err() {
109+
debug!("Rotating connection to the postgres database");
107110
let new_client =
108111
make_db_connection(&self.endpoint, &self.db_name, self.tls.clone()).await?;
109112
*client = new_client;
@@ -145,7 +148,7 @@ where
145148
// Connection must be driven on a separate task, and will resolve when the client is dropped
146149
tokio::spawn(async move {
147150
if let Err(e) = connection.await {
148-
eprintln!("Connection error: {}", e);
151+
warn!("Connection error: {}", e);
149152
}
150153
});
151154
Ok(client)
@@ -173,7 +176,7 @@ where
173176
client.execute(&stmt, &[]).await.map_err(|e| {
174177
Error::new(ErrorKind::Other, format!("Failed to create database {}: {}", db_name, e))
175178
})?;
176-
println!("Created database {}", db_name);
179+
info!("Created database {}", db_name);
177180
}
178181

179182
Ok(())
@@ -291,7 +294,7 @@ where
291294
panic!("We do not allow downgrades");
292295
}
293296

294-
println!("Applying migration(s) {} through {}", migration_start, migrations.len() - 1);
297+
info!("Applying migration(s) {} through {}", migration_start, migrations.len() - 1);
295298

296299
for (idx, &stmt) in (&migrations[migration_start..]).iter().enumerate() {
297300
let _num_rows = tx.execute(stmt, &[]).await.map_err(|e| {

rust/server/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,12 @@ prost = { version = "0.11.6", default-features = false, features = ["std"] }
2222
bytes = "1.4.0"
2323
serde = { version = "1.0.203", default-features = false, features = ["derive"] }
2424
toml = { version = "0.8.9", default-features = false, features = ["parse"] }
25+
log = { version = "0.4.29", default-features = false, features = ["std"] }
26+
chrono = { version = "0.4", default-features = false, features = ["clock"] }
27+
rand = { version = "0.9.2", default-features = false }
28+
29+
[target.'cfg(noop_authorizer)'.dependencies]
30+
api = { path = "../api", features = ["_test_utils"] }
31+
32+
[lints]
33+
workspace = true

rust/server/src/main.rs

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ use tokio::signal::unix::SignalKind;
1717
use hyper::server::conn::http1;
1818
use hyper_util::rt::TokioIo;
1919

20-
use api::auth::{Authorizer, NoopAuthorizer};
20+
use log::{error, info, warn};
21+
22+
use api::auth::Authorizer;
23+
#[cfg(noop_authorizer)]
24+
use api::auth::NoopAuthorizer;
2125
use api::kv_store::KvStore;
2226
#[cfg(feature = "jwt")]
2327
use auth_impls::jwt::JWTAuthorizer;
2428
#[cfg(feature = "sigs")]
2529
use auth_impls::signature::SignatureValidatingAuthorizer;
2630
use impls::postgres_store::{PostgresPlaintextBackend, PostgresTlsBackend};
31+
use util::logger::ServerLogger;
2732
use vss_service::VssService;
2833

2934
mod util;
@@ -38,19 +43,36 @@ fn main() {
3843
std::process::exit(-1);
3944
});
4045

46+
let logger = match ServerLogger::init(config.log_level, &config.log_file) {
47+
Ok(logger) => logger,
48+
Err(e) => {
49+
eprintln!("Failed to initialize logger: {e}");
50+
std::process::exit(-1);
51+
},
52+
};
53+
4154
let runtime = match tokio::runtime::Builder::new_multi_thread().enable_all().build() {
4255
Ok(runtime) => Arc::new(runtime),
4356
Err(e) => {
44-
eprintln!("Failed to setup tokio runtime: {}", e);
57+
error!("Failed to setup tokio runtime: {}", e);
4558
std::process::exit(-1);
4659
},
4760
};
4861

4962
runtime.block_on(async {
63+
// Register SIGHUP handler for log rotation
64+
let mut sighup_stream = match tokio::signal::unix::signal(SignalKind::hangup()) {
65+
Ok(stream) => stream,
66+
Err(e) => {
67+
error!("Failed to register SIGHUP handler: {e}");
68+
std::process::exit(-1);
69+
}
70+
};
71+
5072
let mut sigterm_stream = match tokio::signal::unix::signal(SignalKind::terminate()) {
5173
Ok(stream) => stream,
5274
Err(e) => {
53-
println!("Failed to register for SIGTERM stream: {}", e);
75+
error!("Failed to register for SIGTERM stream: {}", e);
5476
std::process::exit(-1);
5577
},
5678
};
@@ -61,11 +83,11 @@ fn main() {
6183
if let Some(rsa_pem) = config.rsa_pem {
6284
authorizer = match JWTAuthorizer::new(&rsa_pem).await {
6385
Ok(auth) => {
64-
println!("Configured JWT authorizer with RSA public key");
86+
info!("Configured JWT authorizer with RSA public key");
6587
Some(Arc::new(auth))
6688
},
6789
Err(e) => {
68-
println!("Failed to configure JWT authorizer: {}", e);
90+
error!("Failed to configure JWT authorizer: {}", e);
6991
std::process::exit(-1);
7092
},
7193
};
@@ -74,17 +96,25 @@ fn main() {
7496
#[cfg(feature = "sigs")]
7597
{
7698
if authorizer.is_none() {
77-
println!("Configured signature-validating authorizer");
99+
info!("Configured signature-validating authorizer");
78100
authorizer = Some(Arc::new(SignatureValidatingAuthorizer));
79101
}
80102
}
103+
104+
#[cfg(noop_authorizer)]
81105
let authorizer = if let Some(auth) = authorizer {
82106
auth
83107
} else {
84-
println!("No authentication method configured, all storage with the same store id will be commingled.");
108+
warn!("No authentication method configured, all storage with the same store id will be commingled.");
85109
Arc::new(NoopAuthorizer {})
86110
};
87111

112+
#[cfg(not(noop_authorizer))]
113+
let authorizer = authorizer.unwrap_or_else(|| {
114+
error!("No authentication method configured, please configure either `JWTAuthorizer` or `SignatureValidatingAuthorizer`");
115+
std::process::exit(-1);
116+
});
117+
88118
let store: Arc<dyn KvStore> = if let Some(crt_pem) = config.tls_config {
89119
let postgres_tls_backend = PostgresTlsBackend::new(
90120
&config.postgresql_prefix,
@@ -94,10 +124,10 @@ fn main() {
94124
)
95125
.await
96126
.unwrap_or_else(|e| {
97-
println!("Failed to start postgres TLS backend: {}", e);
127+
error!("Failed to start postgres TLS backend: {}", e);
98128
std::process::exit(-1);
99129
});
100-
println!(
130+
info!(
101131
"Connected to PostgreSQL TLS backend with DSN: {}/{}",
102132
config.postgresql_prefix, config.vss_db
103133
);
@@ -110,21 +140,21 @@ fn main() {
110140
)
111141
.await
112142
.unwrap_or_else(|e| {
113-
println!("Failed to start postgres plaintext backend: {}", e);
143+
error!("Failed to start postgres plaintext backend: {}", e);
114144
std::process::exit(-1);
115145
});
116-
println!(
146+
info!(
117147
"Connected to PostgreSQL plaintext backend with DSN: {}/{}",
118148
config.postgresql_prefix, config.vss_db
119149
);
120150
Arc::new(postgres_plaintext_backend)
121151
};
122152

123153
let rest_svc_listener = TcpListener::bind(&config.bind_address).await.unwrap_or_else(|e| {
124-
println!("Failed to bind listening port: {}", e);
154+
error!("Failed to bind listening port: {}", e);
125155
std::process::exit(-1);
126156
});
127-
println!("Listening for incoming connections on {}{}", config.bind_address, crate::vss_service::BASE_PATH_PREFIX);
157+
info!("Listening for incoming connections on {}{}", config.bind_address, crate::vss_service::BASE_PATH_PREFIX);
128158

129159
loop {
130160
tokio::select! {
@@ -135,19 +165,24 @@ fn main() {
135165
let vss_service = VssService::new(Arc::clone(&store), Arc::clone(&authorizer));
136166
runtime.spawn(async move {
137167
if let Err(err) = http1::Builder::new().serve_connection(io_stream, vss_service).await {
138-
eprintln!("Failed to serve connection: {}", err);
168+
warn!("Failed to serve connection: {}", err);
139169
}
140170
});
141171
},
142-
Err(e) => eprintln!("Failed to accept connection: {}", e),
172+
Err(e) => warn!("Failed to accept connection: {}", e),
143173
}
144174
}
145175
_ = tokio::signal::ctrl_c() => {
146-
println!("Received CTRL-C, shutting down..");
176+
info!("Received CTRL-C, shutting down..");
147177
break;
148178
}
179+
_ = sighup_stream.recv() => {
180+
if let Err(e) = logger.reopen() {
181+
error!("Failed to reopen log file on SIGHUP: {e}");
182+
}
183+
}
149184
_ = sigterm_stream.recv() => {
150-
println!("Received SIGTERM, shutting down..");
185+
info!("Received SIGTERM, shutting down..");
151186
break;
152187
}
153188
}

0 commit comments

Comments
 (0)