#datadog #logging

prima_datadog

An opinionated library to share code and approach to Datadog logging in prima.it

15 releases (4 breaking)

new 0.5.0 Dec 6, 2022
0.4.0 Nov 21, 2022
0.3.1 Oct 19, 2022
0.3.0 May 24, 2022
0.1.4 Sep 27, 2021

#210 in Debugging

Download history 154/week @ 2022-08-18 191/week @ 2022-08-25 110/week @ 2022-09-01 207/week @ 2022-09-08 221/week @ 2022-09-15 177/week @ 2022-09-22 134/week @ 2022-09-29 233/week @ 2022-10-06 203/week @ 2022-10-13 374/week @ 2022-10-20 180/week @ 2022-10-27 291/week @ 2022-11-03 228/week @ 2022-11-10 342/week @ 2022-11-17 299/week @ 2022-11-24 305/week @ 2022-12-01

1,221 downloads per month

MIT license

99KB
2K SLoC

Prima Datadog

Build Status

This is an opinionated library to share code and approach to Datadog logging in prima.it

Refer to the official docs for help on how to setup the library in your project


lib.rs:

This is an opinionated library to share code and approach to Datadog logging in prima.it

Getting started

You need to call [Datadog::init] in your main binary, and to do so you'll need as argument a type that implements the [Configuration] trait. If you never call [Datadog::init] in your binary NO metrics will be sent.

Inside the [configuration] you'll find an [implementation of this trait][configuration::PrimaConfiguration] tailored for prima.it needs.

use prima_datadog::{*, configuration::PrimaConfiguration};

// initializes the PrimaConfiguration struct
let configuration = PrimaConfiguration::new(
    "0.0.0.0:1234", // to address
    "0.0.0.0:0", // from address
    "service_name", // namespace for all metrics
    "production".parse().unwrap() // environment
);

// Initializes a Datadog instance
Datadog::init(configuration);

Then you can use the macros exposed at the base level of the module. All macros accepts

  • a string value or a path to a type that implements AsRef as first argument.
  • zero or more arguments, separated by comma ,, for the metrics that needs more data. For example count! and timing! accepts a number while service_check! accepts a [ServiceStatus] and a [ServiceCheckOptions]
  • a list of tags (which is separated from the rest of the arguments by semicolon ;) in the form of "name" => "value"
# use prima_datadog::{*, configuration::PrimaConfiguration};
# let configuration = PrimaConfiguration::new(
#     "0.0.0.0:1234", // to address
#     "0.0.0.0:0", // from address
#     "service_name", // namespace for all metrics
#     "production".parse().unwrap() // environment
# );
# Datadog::init(configuration);
incr!("test");
# incr!("test"; "some" => "data");
# decr!("test");
decr!("test"; "some" => "data");
count!("test", 20);
count!("test", 10; "some" => "data");
time!("test", || { println!("expensive computation");});
time!("test", || { println!("expensive computation");}; "some" => "data");
# timing!("test", 20);
timing!("test", 20; "some" => "data");
# gauge!("test", "gauge value");
gauge!("test", "gauge value"; "some" => "data");
# histogram!("test", "histogram value");
histogram!("test", "histogram value"; "some" => "data");
# distribution!("test", "distribution value");
distribution!("test", "distribution value"; "some" => "data");
# set!("test", "set value");
set!("test", "set value"; "some" => "data");
service_check!("test", ServiceStatus::OK);
service_check!("test", ServiceStatus::OK, ServiceCheckOptions::default());
# event!("test", "test event");
event!("test", "test event"; "some" => "data");

This is an example of a custom metric, in this case based on an enum type, but it can really be whatever you want, as long as it implements AsRef

# use prima_datadog::{*, configuration::PrimaConfiguration};
# let configuration = PrimaConfiguration::new(
#     "0.0.0.0:1234", // to address
#     "0.0.0.0:0", // from address
#     "service_name", // namespace for all metrics
#     "production".parse().unwrap() // environment
# );
# Datadog::init(configuration);
enum Metric {
    John,
    Paul,
    George,
    Ringo,
}

impl AsRef<str> for Metric {
    fn as_ref(&self) -> &str {
        match self {
            Metric::John => "john",
            Metric::Paul => "paul",
            Metric::George => "george",
            Metric::Ringo => "ringo",
        }
    }
}

// now you can do
incr!(Metric::John; "play" => "guitar");
incr!(Metric::Paul; "play" => "bass");
incr!(Metric::George; "play" => "sitar");
incr!(Metric::Ringo; "play" => "drums");

Note - Avoid high tag cardinality!

It's important to avoid passing a large number of values for a given tag, as Datadog tracks each unique combination of tag values as a separate metric, which can significantly impact billing. For example, avoid passing things like user IDs, session IDs, request IDs, or other values that vary significantly. See https://docs.datadoghq.com/getting_started/tagging/ for more information.

Users may configure some actions to be taken when a metric cardinality threshold is exceeded. See [tracker::TagTrackerConfiguration] for more information.

References

Dependencies

~1.1–2MB
~37K SLoC