refactor: improve debug logging (#264)

This commit is contained in:
Stepan Kuzmin 2021-10-12 19:01:25 +03:00 committed by GitHub
parent 206307fd22
commit a9cf508c33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 51 additions and 37 deletions

View File

@ -277,7 +277,7 @@ DECLARE
BEGIN BEGIN
SELECT INTO mvt ST_AsMVT(tile, 'public.function_source', 4096, 'geom') FROM ( SELECT INTO mvt ST_AsMVT(tile, 'public.function_source', 4096, 'geom') FROM (
SELECT SELECT
ST_AsMVTGeom(ST_Transform(geom, 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom
FROM public.table_source FROM public.table_source
WHERE geom && TileBBox(z, x, y, 4326) WHERE geom && TileBBox(z, x, y, 4326)
) as tile WHERE geom IS NOT NULL; ) as tile WHERE geom IS NOT NULL;

View File

@ -78,14 +78,14 @@ pub fn generate_config(args: Args, pool: &Pool) -> io::Result<Config> {
} }
fn setup_from_config(file_name: String) -> io::Result<(Config, Pool)> { fn setup_from_config(file_name: String) -> io::Result<(Config, Pool)> {
let config = read_config(&file_name).map_err(prettify_error("Can't read config"))?; let config = read_config(&file_name).map_err(prettify_error("Can't read config".to_owned()))?;
let pool = setup_connection_pool( let pool = setup_connection_pool(
&config.connection_string, &config.connection_string,
Some(config.pool_size), Some(config.pool_size),
config.danger_accept_invalid_certs, config.danger_accept_invalid_certs,
) )
.map_err(prettify_error("Can't setup connection pool"))?; .map_err(prettify_error("Can't setup connection pool".to_owned()))?;
if let Some(table_sources) = &config.table_sources { if let Some(table_sources) = &config.table_sources {
for table_source in table_sources.values() { for table_source in table_sources.values() {
@ -127,10 +127,11 @@ fn setup_from_args(args: Args) -> io::Result<(Config, Pool)> {
args.flag_pool_size, args.flag_pool_size,
args.flag_danger_accept_invalid_certs, args.flag_danger_accept_invalid_certs,
) )
.map_err(prettify_error("Can't setup connection pool"))?; .map_err(prettify_error("Can't setup connection pool".to_owned()))?;
info!("Scanning database"); info!("Scanning database");
let config = generate_config(args, &pool).map_err(prettify_error("Can't generate config"))?; let config =
generate_config(args, &pool).map_err(prettify_error("Can't generate config".to_owned()))?;
Ok((config, pool)) Ok((config, pool))
} }
@ -168,7 +169,7 @@ fn start(args: Args) -> io::Result<actix::SystemRunner> {
}; };
let matches = check_postgis_version(REQUIRED_POSTGIS_VERSION, &pool) let matches = check_postgis_version(REQUIRED_POSTGIS_VERSION, &pool)
.map_err(prettify_error("Can't check PostGIS version"))?; .map_err(prettify_error("Can't check PostGIS version".to_owned()))?;
if !matches { if !matches {
std::process::exit(-1); std::process::exit(-1);
@ -187,7 +188,7 @@ fn main() -> io::Result<()> {
let args = Docopt::new(USAGE) let args = Docopt::new(USAGE)
.and_then(|d| d.deserialize::<Args>()) .and_then(|d| d.deserialize::<Args>())
.map_err(prettify_error("Can't parse CLI arguments"))?; .map_err(prettify_error("Can't parse CLI arguments".to_owned()))?;
let args = parse_env(args); let args = parse_env(args);

View File

@ -93,7 +93,7 @@ impl Source for CompositeSource {
let tile: Tile = conn let tile: Tile = conn
.query_one(tile_query.as_str(), &[]) .query_one(tile_query.as_str(), &[])
.map(|row| row.get("tile")) .map(|row| row.get("tile"))
.map_err(prettify_error("Can't get composite source tile"))?; .map_err(prettify_error("Can't get composite source tile".to_owned()))?;
Ok(tile) Ok(tile)
} }

View File

@ -57,7 +57,7 @@ pub fn read_config(file_name: &str) -> io::Result<Config> {
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;
let config_builder: ConfigBuilder = serde_yaml::from_str(contents.as_str()) let config_builder: ConfigBuilder = serde_yaml::from_str(contents.as_str())
.map_err(prettify_error("Can't read config file"))?; .map_err(prettify_error("Can't read config file".to_owned()))?;
Ok(config_builder.finalize()) Ok(config_builder.finalize())
} }

View File

@ -18,7 +18,7 @@ fn make_tls_connector(danger_accept_invalid_certs: bool) -> io::Result<MakeTlsCo
let connector = TlsConnector::builder() let connector = TlsConnector::builder()
.danger_accept_invalid_certs(danger_accept_invalid_certs) .danger_accept_invalid_certs(danger_accept_invalid_certs)
.build() .build()
.map_err(prettify_error("Can't build TLS connection"))?; .map_err(prettify_error("Can't build TLS connection".to_owned()))?;
let tls_connector = MakeTlsConnector::new(connector); let tls_connector = MakeTlsConnector::new(connector);
Ok(tls_connector) Ok(tls_connector)
@ -30,7 +30,7 @@ pub fn setup_connection_pool(
danger_accept_invalid_certs: bool, danger_accept_invalid_certs: bool,
) -> io::Result<Pool> { ) -> io::Result<Pool> {
let config = postgres::config::Config::from_str(cn_str) let config = postgres::config::Config::from_str(cn_str)
.map_err(prettify_error("Can't parse connection string"))?; .map_err(prettify_error("Can't parse connection string".to_owned()))?;
let tls_connector = make_tls_connector(danger_accept_invalid_certs)?; let tls_connector = make_tls_connector(danger_accept_invalid_certs)?;
let manager = PostgresConnectionManager::new(config, tls_connector); let manager = PostgresConnectionManager::new(config, tls_connector);
@ -38,15 +38,15 @@ pub fn setup_connection_pool(
let pool = r2d2::Pool::builder() let pool = r2d2::Pool::builder()
.max_size(pool_size.unwrap_or(20)) .max_size(pool_size.unwrap_or(20))
.build(manager) .build(manager)
.map_err(prettify_error("Can't build connection pool"))?; .map_err(prettify_error("Can't build connection pool".to_owned()))?;
Ok(pool) Ok(pool)
} }
pub fn get_connection(pool: &Pool) -> io::Result<Connection> { pub fn get_connection(pool: &Pool) -> io::Result<Connection> {
let connection = pool let connection = pool.get().map_err(prettify_error(
.get() "Can't retrieve connection from the pool".to_owned(),
.map_err(prettify_error("Can't retrieve connection from the pool"))?; ))?;
Ok(connection) Ok(connection)
} }
@ -57,7 +57,7 @@ pub fn select_postgis_verion(pool: &Pool) -> io::Result<String> {
let version = connection let version = connection
.query_one(include_str!("scripts/get_postgis_version.sql"), &[]) .query_one(include_str!("scripts/get_postgis_version.sql"), &[])
.map(|row| row.get::<_, String>("postgis_version")) .map(|row| row.get::<_, String>("postgis_version"))
.map_err(prettify_error("Can't get PostGIS version"))?; .map_err(prettify_error("Can't get PostGIS version".to_owned()))?;
Ok(version) Ok(version)
} }
@ -65,11 +65,13 @@ pub fn select_postgis_verion(pool: &Pool) -> io::Result<String> {
pub fn check_postgis_version(required_postgis_version: &str, pool: &Pool) -> io::Result<bool> { pub fn check_postgis_version(required_postgis_version: &str, pool: &Pool) -> io::Result<bool> {
let postgis_version = select_postgis_verion(pool)?; let postgis_version = select_postgis_verion(pool)?;
let req = VersionReq::parse(required_postgis_version) let req = VersionReq::parse(required_postgis_version).map_err(prettify_error(
.map_err(prettify_error("Can't parse required PostGIS version"))?; "Can't parse required PostGIS version".to_owned(),
))?;
let version = Version::parse(postgis_version.as_str()) let version = Version::parse(postgis_version.as_str()).map_err(prettify_error(
.map_err(prettify_error("Can't parse database PostGIS version"))?; "Can't parse database PostGIS version".to_owned(),
))?;
let matches = req.matches(&version); let matches = req.matches(&version);

View File

@ -67,13 +67,16 @@ impl Source for FunctionSource {
&[Type::INT4, Type::INT4, Type::INT4, Type::JSON], &[Type::INT4, Type::INT4, Type::INT4, Type::JSON],
) )
.map_err(prettify_error( .map_err(prettify_error(
"Can't create prepared statement for the tile", "Can't create prepared statement for the tile".to_owned(),
))?; ))?;
let tile = conn let tile = conn
.query_one(&query, &[&xyz.x, &xyz.y, &xyz.z, &query_json]) .query_one(&query, &[&xyz.x, &xyz.y, &xyz.z, &query_json])
.map(|row| row.get(self.function.as_str())) .map(|row| row.get(self.function.as_str()))
.map_err(prettify_error("Can't get function source tile"))?; .map_err(prettify_error(format!(
"Can't get \"{}\" tile at /{}/{}/{} with {:?} params",
self.id, &xyz.z, &xyz.x, &xyz.z, &query_json
)))?;
Ok(tile) Ok(tile)
} }
@ -84,7 +87,7 @@ pub fn get_function_sources(conn: &mut Connection) -> Result<FunctionSources, io
let rows = conn let rows = conn
.query(include_str!("scripts/get_function_sources.sql"), &[]) .query(include_str!("scripts/get_function_sources.sql"), &[])
.map_err(prettify_error("Can't get function sources"))?; .map_err(prettify_error("Can't get function sources".to_owned()))?;
for row in &rows { for row in &rows {
let schema: String = row.get("specific_schema"); let schema: String = row.get("specific_schema");

View File

@ -59,6 +59,11 @@ struct CompositeTileRequest {
format: String, format: String,
} }
fn map_internal_error<T: std::fmt::Display>(e: T) -> Error {
error!("{}", e.to_string());
error::ErrorInternalServerError(e.to_string())
}
async fn get_health() -> Result<HttpResponse, Error> { async fn get_health() -> Result<HttpResponse, Error> {
let response = HttpResponse::Ok().body("OK"); let response = HttpResponse::Ok().body("OK");
Ok(response) Ok(response)
@ -77,8 +82,8 @@ async fn get_table_sources(state: web::Data<AppState>) -> Result<HttpResponse, E
.db .db
.send(messages::GetTableSources {}) .send(messages::GetTableSources {})
.await .await
.map_err(|_| HttpResponse::InternalServerError())? .map_err(map_internal_error)?
.map_err(|_| HttpResponse::InternalServerError())?; .map_err(map_internal_error)?;
state.coordinator.do_send(messages::RefreshTableSources { state.coordinator.do_send(messages::RefreshTableSources {
table_sources: Some(table_sources.clone()), table_sources: Some(table_sources.clone()),
@ -192,8 +197,8 @@ async fn get_composite_source_tile(
.db .db
.send(message) .send(message)
.await .await
.map_err(|_| HttpResponse::InternalServerError())? .map_err(map_internal_error)?
.map_err(|_| HttpResponse::InternalServerError())?; .map_err(map_internal_error)?;
match tile.len() { match tile.len() {
0 => Ok(HttpResponse::NoContent() 0 => Ok(HttpResponse::NoContent()
@ -218,8 +223,8 @@ async fn get_function_sources(state: web::Data<AppState>) -> Result<HttpResponse
.db .db
.send(messages::GetFunctionSources {}) .send(messages::GetFunctionSources {})
.await .await
.map_err(|_| HttpResponse::InternalServerError())? .map_err(map_internal_error)?
.map_err(|_| HttpResponse::InternalServerError())?; .map_err(map_internal_error)?;
state.coordinator.do_send(messages::RefreshFunctionSources { state.coordinator.do_send(messages::RefreshFunctionSources {
function_sources: Some(function_sources.clone()), function_sources: Some(function_sources.clone()),
@ -310,8 +315,8 @@ async fn get_function_source_tile(
.db .db
.send(message) .send(message)
.await .await
.map_err(|_| HttpResponse::InternalServerError())? .map_err(map_internal_error)?
.map_err(|_| HttpResponse::InternalServerError())?; .map_err(map_internal_error)?;
match tile.len() { match tile.len() {
0 => Ok(HttpResponse::NoContent() 0 => Ok(HttpResponse::NoContent()

View File

@ -31,7 +31,7 @@ impl TableSource {
let mercator_bounds = utils::tilebbox(xyz); let mercator_bounds = utils::tilebbox(xyz);
let properties = if self.properties.is_empty() { let properties = if self.properties.is_empty() {
"".to_string() String::new()
} else { } else {
let properties = self let properties = self
.properties .properties
@ -111,7 +111,10 @@ impl Source for TableSource {
let tile: Tile = conn let tile: Tile = conn
.query_one(tile_query.as_str(), &[]) .query_one(tile_query.as_str(), &[])
.map(|row| row.get("st_asmvt")) .map(|row| row.get("st_asmvt"))
.map_err(utils::prettify_error("Can't get table source tile"))?; .map_err(utils::prettify_error(format!(
"Can't get \"{}\" tile at /{}/{}/{}",
self.id, &xyz.z, &xyz.x, &xyz.z
)))?;
Ok(tile) Ok(tile)
} }
@ -126,7 +129,7 @@ pub fn get_table_sources(conn: &mut Connection) -> Result<TableSources, io::Erro
let rows = conn let rows = conn
.query(include_str!("scripts/get_table_sources.sql"), &[]) .query(include_str!("scripts/get_table_sources.sql"), &[])
.map_err(utils::prettify_error("Can't get table sources"))?; .map_err(utils::prettify_error("Can't get table sources".to_owned()))?;
for row in &rows { for row in &rows {
let schema: String = row.get("f_table_schema"); let schema: String = row.get("f_table_schema");
@ -159,7 +162,7 @@ pub fn get_table_sources(conn: &mut Connection) -> Result<TableSources, io::Erro
let properties = utils::json_to_hashmap(&row.get("properties")); let properties = utils::json_to_hashmap(&row.get("properties"));
let source = TableSource { let source = TableSource {
id: id.to_string(), id: id.to_owned(),
schema, schema,
table, table,
id_column: None, id_column: None,

View File

@ -5,7 +5,7 @@ use postgis::{ewkb, LineString, Point, Polygon};
use postgres::types::Json; use postgres::types::Json;
use serde_json::Value; use serde_json::Value;
pub fn prettify_error<E: std::fmt::Display>(message: &'static str) -> impl Fn(E) -> std::io::Error { pub fn prettify_error<E: std::fmt::Display>(message: String) -> impl Fn(E) -> std::io::Error {
move |error| std::io::Error::new(std::io::ErrorKind::Other, format!("{}: {}", message, error)) move |error| std::io::Error::new(std::io::ErrorKind::Other, format!("{}: {}", message, error))
} }
@ -35,7 +35,7 @@ pub fn json_to_hashmap(value: &serde_json::Value) -> HashMap<String, String> {
let object = value.as_object().unwrap(); let object = value.as_object().unwrap();
for (key, value) in object { for (key, value) in object {
let string_value = value.as_str().unwrap(); let string_value = value.as_str().unwrap();
hashmap.insert(key.to_string(), string_value.to_string()); hashmap.insert(key.to_owned(), string_value.to_owned());
} }
hashmap hashmap