mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-10 06:52:55 +00:00
## Summary of changes ### RequestMonitoring We want to add an event stream with information on each request for easier analysis than what we can do with diagnostic logs alone (https://github.com/neondatabase/cloud/issues/8807). This RequestMonitoring will keep a record of the final state of a request. On drop it will be pushed into a queue to be uploaded. Because this context is a bag of data, I don't want this information to impact logic of request handling. I personally think that weakly typed data (such as all these options) makes for spaghetti code. I will however allow for this data to impact rate-limiting and blocking of requests, as this does not _really_ change how a request is handled. ### Parquet Each `RequestMonitoring` is flushed into a channel where it is converted into `RequestData`, which is accumulated into parquet files. Each file will have a certain number of rows per row group, and several row groups will eventually fill up the file, which we then upload to S3. We will also upload smaller files if they take too long to construct.
65 lines
2.0 KiB
Rust
65 lines
2.0 KiB
Rust
use std::{error::Error as StdError, fmt, io};
|
|
|
|
/// Upcast (almost) any error into an opaque [`io::Error`].
|
|
pub fn io_error(e: impl Into<Box<dyn StdError + Send + Sync>>) -> io::Error {
|
|
io::Error::new(io::ErrorKind::Other, e)
|
|
}
|
|
|
|
/// A small combinator for pluggable error logging.
|
|
pub fn log_error<E: fmt::Display>(e: E) -> E {
|
|
tracing::error!("{e}");
|
|
e
|
|
}
|
|
|
|
/// Marks errors that may be safely shown to a client.
|
|
/// This trait can be seen as a specialized version of [`ToString`].
|
|
///
|
|
/// NOTE: This trait should not be implemented for [`anyhow::Error`], since it
|
|
/// is way too convenient and tends to proliferate all across the codebase,
|
|
/// ultimately leading to accidental leaks of sensitive data.
|
|
pub trait UserFacingError: fmt::Display {
|
|
/// Format the error for client, stripping all sensitive info.
|
|
///
|
|
/// Although this might be a no-op for many types, it's highly
|
|
/// recommended to override the default impl in case error type
|
|
/// contains anything sensitive: various IDs, IP addresses etc.
|
|
#[inline(always)]
|
|
fn to_string_client(&self) -> String {
|
|
self.to_string()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub enum ErrorKind {
|
|
/// Wrong password, unknown endpoint, protocol violation, etc...
|
|
User,
|
|
|
|
/// Network error between user and proxy. Not necessarily user error
|
|
Disconnect,
|
|
|
|
/// Proxy self-imposed rate limits
|
|
RateLimit,
|
|
|
|
/// internal errors
|
|
Service,
|
|
|
|
/// Error communicating with control plane
|
|
ControlPlane,
|
|
|
|
/// Error communicating with compute
|
|
Compute,
|
|
}
|
|
|
|
impl ErrorKind {
|
|
pub fn to_str(&self) -> &'static str {
|
|
match self {
|
|
ErrorKind::User => "request failed due to user error",
|
|
ErrorKind::Disconnect => "client disconnected",
|
|
ErrorKind::RateLimit => "request cancelled due to rate limit",
|
|
ErrorKind::Service => "internal service error",
|
|
ErrorKind::ControlPlane => "non-retryable control plane error",
|
|
ErrorKind::Compute => "non-retryable compute error (or exhausted retry capacity)",
|
|
}
|
|
}
|
|
}
|