1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#![warn(missing_docs)]
//#![deny(warnings)]
//! Provides a client interface for [AWS X-Ray](https://aws.amazon.com/xray/)
//!
//! ### Examples
//!
//! #### Subsegment of AWS service operation
//!
//! **The [`xray_lite_aws_sdk`](https://docs.rs/xray-lite-aws-sdk) extension is
//! recommended for tracing operations through
//! [AWS SDK for Rust](https://aws.amazon.com/sdk-for-rust/).**
//!
//! Here is an example to record a subsegment of an AWS service operation
//! within a Lambda function invocation instrumented with AWS X-Ray:
//!
//! ```
//! use xray_lite::{AwsNamespace, Context, DaemonClient, SubsegmentContext};
//!
//! fn main() {
//!    // reads AWS_XRAY_DAEMON_ADDRESS
//!    # std::env::set_var("AWS_XRAY_DAEMON_ADDRESS", "127.0.0.1:2000");
//!    let client = DaemonClient::from_lambda_env().unwrap();
//!    // reads _X_AMZN_TRACE_ID
//!    # std::env::set_var("_X_AMZN_TRACE_ID", "Root=1-65dfb5a1-0123456789abcdef01234567;Parent=0123456789abcdef;Sampled=1");
//!    let context = SubsegmentContext::from_lambda_env(client).unwrap();
//!
//!    do_s3_get_object(&context);
//! }
//!
//! fn do_s3_get_object(context: &impl Context) {
//!     // subsegment will have the name "S3" and `aws.operation` "GetObject"
//!     let subsegment = context.enter_subsegment(AwsNamespace::new("S3", "GetObject"));
//!
//!     // call S3 GetObject ...
//!
//!     // if you are using `aws-sdk-s3` crate, you can update the subsegment
//!     // with the request ID. suppose `out` is the output of the `GetObject`
//!     // operation:
//!     //
//!     //     subsegment
//!     //         .namespace_mut()
//!     //         .zip(out.request_id())
//!     //         .map(|(ns, id)| ns.request_id(id));
//!
//!     // the subsegment will be ended and reported when it is dropped
//! }
//! ```
//!
//! #### Subsegment of remote service call
//!
//! Here is an example to record a subsegment of a remote service call within a
//! Lambda function invocation intstrumented with AWS X-Ray:
//!
//! ```
//! use xray_lite::{Context, DaemonClient, RemoteNamespace, SubsegmentContext};
//!
//! fn main() {
//!    // reads AWS_XRAY_DAEMON_ADDRESS
//!    # std::env::set_var("AWS_XRAY_DAEMON_ADDRESS", "127.0.0.1:2000");
//!    let client = DaemonClient::from_lambda_env().unwrap();
//!    // reads _X_AMZN_TRACE_ID
//!    # std::env::set_var("_X_AMZN_TRACE_ID", "Root=1-65dfb5a1-0123456789abcdef01234567;Parent=0123456789abcdef;Sampled=1");
//!    let context = SubsegmentContext::from_lambda_env(client).unwrap();
//!
//!    do_some_request(&context);
//! }
//!
//! fn do_some_request(context: &impl Context) {
//!     // subsegment will have the name "readme example",
//!     // `http.request.method` "POST", and `http.request.url` "https://codemonger.io/"
//!     let subsegment = context.enter_subsegment(RemoteNamespace::new(
//!         "readme example",
//!         "GET",
//!         "https://codemonger.io/",
//!     ));
//!
//!     // do some request ...
//!
//!     // the subsegment will be ended and reported when it is dropped
//! }
//! ```
//!
//! #### Custom subsegment
//!
//! Here is an example to record a custom subsegment within a Lambda function
//! invocation intstrumented with AWS X-Ray:
//!
//! ```
//! use xray_lite::{Context, DaemonClient, CustomNamespace, SubsegmentContext};
//!
//! fn main() {
//!    // reads AWS_XRAY_DAEMON_ADDRESS
//!    # std::env::set_var("AWS_XRAY_DAEMON_ADDRESS", "127.0.0.1:2000");
//!    let client = DaemonClient::from_lambda_env().unwrap();
//!    // reads _X_AMZN_TRACE_ID
//!    # std::env::set_var("_X_AMZN_TRACE_ID", "Root=1-65dfb5a1-0123456789abcdef01234567;Parent=0123456789abcdef;Sampled=1");
//!    let context = SubsegmentContext::from_lambda_env(client).unwrap()
//!        .with_name_prefix("readme_example.");
//!
//!    do_something(&context);
//! }
//!
//! fn do_something(context: &impl Context) {
//!     // subsegment will have the name "readme_example.do_something"
//!     let subsegment = context.enter_subsegment(CustomNamespace::new("do_something"));
//!
//!     // do some thing ...
//!
//!     // the subsegment will be ended and reported when it is dropped
//! }
//! ```
//!
//! ### Acknowledgements
//!
//! This crate is based on the [great work](https://github.com/softprops/xray)
//! by [Doug Tangren (softprops)](https://github.com/softprops).

mod client;
mod context;
mod epoch;
mod error;
mod header;
mod hexbytes;
mod lambda;
mod namespace;
mod segment;
mod segment_id;
mod session;
mod trace_id;

pub use crate::{
    client::{Client, DaemonClient, InfallibleClient, IntoInfallibleClient},
    context::{Context, InfallibleContext, IntoInfallibleContext, SubsegmentContext},
    epoch::Seconds,
    error::{Error, Result},
    header::Header,
    namespace::{AwsNamespace, CustomNamespace, Namespace, RemoteNamespace},
    segment::*,
    segment_id::SegmentId,
    session::SubsegmentSession,
    trace_id::TraceId,
};