Drop custom errors

This commit is contained in:
Francis Lalonde 2018-12-18 14:17:12 -05:00
parent ce3273bafa
commit 1eb2c01e01
7 changed files with 64 additions and 96 deletions

View File

@ -1,26 +1,30 @@
# The dipstick handbook
This handbook's purpose is to get you started instrumenting your apps with Dipstick
and give an idea of what's possible.
This handbook's purpose is to get you started instrumenting your apps and give an idea of what's possible.
It is not a full-on cookbook (yet) - some reader experimentation may be required!
# Background
Dipstick was born of the desire to build a metrics library that would allow to select from,
switch between and combine multiple backends.
Such a design has multiple benefits:
Dipstick is a structured metrics library that allows to combine, select from, and switch between multiple metrics backends.
Because counters, timers and gauges declared in the code are not tied to a specific implementation.
This has multiple benefits:
- simplified instrumentation
- flexible configuration
- flexible compile-time or runtime configuration
- easier metrics testing
For example, using a compile-time feature switch, metrics could be collected directly to hash map at test time
but be sent over the network and written to a file at runtime, as described by external configuration.
Because of its Rust nature, performance, safety and ergonomy are also prime concerns.
## API Overview
# API Overview
Dipstick's API is split between _input_ and _output_ layers.
The input layer provides named metrics such as counters and timers to be used by the application.
The output layer controls how metric values will be recorded and emitted by the configured backend(s).
Input and output layers are decoupled, making code instrumentation independent of output configuration.
Intermediates can also be added between input and output for features or performance characteristics.
Intermediates can also be added between input and output for specific features or performance characteristics.
Although this handbook covers input before output, implementation can certainly be performed the other way around.
Although this handbook covers input before output, implementation of metrics can certainly be performed the other way around.
For more details, consult the [docs](https://docs.rs/dipstick/).

35
HANDBOOK.md.skt.md Normal file
View File

@ -0,0 +1,35 @@
Templates
Use `cargo test --features="skeptic"` to run the examples in the README using the `skeptic` crate.
```rust,skt-run
#[macro_use]
extern crate dipstick;
use dipstick::*;
use std::time::Duration;
fn main() {{
{}
}}
```
```rust,skt-fail
extern crate dipstick;
use dipstick::*;
use std::result::Result;
use std::time::Duration;
fn main() {{
run().ok();
}}
fn run() -> Result<(), Error> {{
{}
Ok(())
}}
```
```rust,skt-plain
{}
```

View File

@ -61,7 +61,7 @@ metrics! { METRICS = "my_app" => {
}
fn main() {
METRICS.set_target(Graphite::send_to("graphite.com:2003").unwrap().input());
METRICS.set_target(Graphite::send_to("localhost:2003").unwrap().input());
COUNTER.count(32);
}
```
@ -76,6 +76,14 @@ in the `[dependencies]` section:
dipstick = "0.7.0"
```
## TODO / Missing / Weak points
- Prometheus support is still primitive. Official prometheus-rust crate is used but Labels/Tags are not passed to it.
- No backend for "pull" metrics yet. Should at least provide tiny-http listener capability.
- No quick integration feature with common frameworks (Actix, etc.) is provided yet.
- Thread Local buckets could be nice.
- "Rolling" aggregators would be nice for pull metrics. Current bucket impl resets after flush.
## License
Dipstick is licensed under the terms of the Apache 2.0 and MIT license.

View File

@ -2,10 +2,9 @@
extern crate skeptic;
fn main() {
// generates handbook tests for `README.md`.
// generates documentation tests.
#[cfg(feature="skeptic")]
skeptic::generate_doc_tests(&["README.md", "HANDBOOK.md"]);
}

View File

@ -1,5 +1,5 @@
//! A demonstration of customization of exported aggregated metrics.
//! Using match on origin metric kind or score type to alter publication output.
//! A dropwizard-like configuration using three buckets
//! aggregating one, five and fifteen minutes of data.
#[macro_use]
extern crate dipstick;

View File

@ -1,83 +1,5 @@
//! Error-chain like mechanism, without the error-chain dependency.
use std::io;
use std::error;
use std::fmt::{self, Display, Formatter};
use std::error::Error;
use std::result;
use std::sync::mpsc;
use queue::queue_in;
use queue::queue_out;
use prometheus;
use self::Error::*;
/// Any error that may result from dipstick usage.
#[derive(Debug)]
pub enum Error {
/// A generic I/O error.
IO(io::Error),
/// An error from the async metric queue.
InputQueue(mpsc::SendError<queue_in::InputQueueCmd>),
/// An error from the async metric queue.
OutputQueue(mpsc::SendError<queue_out::OutputQueueCmd>),
/// An error from the async metric queue.
Prometheus(prometheus::Error),
}
impl Display for Error {
fn fmt(&self, formatter: &mut Formatter) -> result::Result<(), fmt::Error> {
match *self {
IO(ref err) => err.fmt(formatter),
InputQueue(ref err) => err.fmt(formatter),
OutputQueue(ref err) => err.fmt(formatter),
Prometheus(ref err) => err.fmt(formatter),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
IO(ref err) => err.description(),
InputQueue(ref err) => err.description(),
OutputQueue(ref err) => err.description(),
Prometheus(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
IO(ref err) => Some(err),
InputQueue(ref err) => Some(err),
OutputQueue(ref err) => Some(err),
Prometheus(ref err) => Some(err),
}
}
}
/// The result type for dipstick operations that may fail.
pub type Result<T> = result::Result<T, Error>;
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
IO(err)
}
}
impl From<mpsc::SendError<queue_in::InputQueueCmd>> for Error {
fn from(err: mpsc::SendError<queue_in::InputQueueCmd>) -> Self {
InputQueue(err)
}
}
impl From<mpsc::SendError<queue_out::OutputQueueCmd>> for Error {
fn from(err: mpsc::SendError<queue_out::OutputQueueCmd>) -> Self {
OutputQueue(err)
}
}
impl From<prometheus::Error> for Error {
fn from(err: prometheus::Error) -> Self {
Prometheus(err)
}
}
/// Just put any error in a box.
pub type Result<T> = result::Result<T, Box<Error>>;

View File

@ -34,7 +34,7 @@ pub use core::input::{Input, InputDyn, InputScope, InputMetric, Counter, Timer,
pub use core::output::{Output, OutputDyn, OutputScope, OutputMetric};
pub use core::scheduler::{ScheduleFlush, CancelHandle};
pub use core::out_lock::{LockingScopeBox};
pub use core::error::{Error, Result};
pub use core::error::{Result};
pub use core::clock::{TimeHandle};
pub use core::label::{Labels, AppLabel, ThreadLabel};