Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ rand = "0.10"
[dependencies.temporalio-common]
path = "../common"
version = "0.3"
default-features = false

[dev-dependencies]
assert_matches = "1"
Expand Down
15 changes: 7 additions & 8 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exclude = ["protos/*/.github/*"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
history_builders = ["rand"]
history_builders = ["dep:rand"]
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P sure dep: prefix is required here

otel = ["dep:opentelemetry", "dep:opentelemetry_sdk", "dep:opentelemetry-otlp"]
prometheus = [
"dep:prometheus",
Expand All @@ -26,12 +26,8 @@ prometheus = [
envconfig = ["dep:toml", "dep:dirs"]
serde_serialize = []
test-utilities = ["history_builders"]
core-based-sdk = [
"prometheus",
"envconfig",
"dep:ringbuf",
"dep:futures-channel",
]
core-telemetry-bridge = ["dep:ringbuf", "dep:futures-channel"]
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Splitting this out so we can allow Rust SDK users to opt out of prometheus/envconfig

core-based-sdk = ["core-telemetry-bridge", "prometheus", "envconfig"]

[dependencies]
anyhow = "1.0"
Expand Down Expand Up @@ -85,7 +81,10 @@ tokio = { version = "1.47", default-features = false, features = [
"rt",
], optional = true }
toml = { version = "1.0", optional = true }
tonic = { workspace = true, default-features = false, features = ["transport", "codegen"] }
tonic = { workspace = true, default-features = false, features = [
"transport",
"codegen",
] }
tonic-prost = { workspace = true }
tracing = "0.1"
# TODO [rust-sdk-branch]: Is it reasonable to make this optional?
Expand Down
28 changes: 14 additions & 14 deletions crates/common/src/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// Metric instrument types and the [`CoreMeter`] trait.
pub mod metrics;

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
mod log_export;
#[cfg(feature = "otel")]
mod otel;
Expand Down Expand Up @@ -31,10 +31,10 @@ use tracing::{Level, Subscriber};
use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt};
use url::Url;

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
use crate::telemetry::log_export::CoreLogConsumerLayer;

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
pub use log_export::{CoreLogBuffer, CoreLogBufferedConsumer, CoreLogStreamConsumer};
#[cfg(feature = "otel")]
pub use otel::build_otlp_metric_exporter;
Expand Down Expand Up @@ -200,13 +200,13 @@ pub enum Logger {
/// An [EnvFilter](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html) filter string.
filter: String,
},
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
/// Forward logs to Lang - collectable with `fetch_global_buffered_logs`.
Forward {
/// An [EnvFilter](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html) filter string.
filter: String,
},
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
/// Push logs to Lang. Can be used with
/// temporalio_sdk_core::telemetry::log_export::CoreLogBufferedConsumer to buffer.
Push {
Expand Down Expand Up @@ -277,7 +277,7 @@ pub trait CoreLogConsumer: Send + Sync + Debug {
fn on_log(&self, log: CoreLog);
}

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
const FORWARD_LOG_BUFFER_SIZE: usize = 2048;

/// Help you construct an [EnvFilter] compatible filter string which will forward all core module
Expand All @@ -291,7 +291,7 @@ pub fn construct_filter_string(core_level: Level, other_level: Level) -> String
/// Holds initialized tracing/metrics exporters, etc
pub struct TelemetryInstance {
metric_prefix: String,
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
logs_out: Option<parking_lot::Mutex<CoreLogBuffer>>,
metrics: Option<Arc<dyn CoreMeter + 'static>>,
/// The tracing subscriber which is associated with this telemetry instance. May be `None` if
Expand Down Expand Up @@ -372,7 +372,7 @@ pub fn remove_trace_subscriber_for_current_thread() {
SUB_GUARD.take();
}

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
impl CoreTelemetry for TelemetryInstance {
fn fetch_buffered_logs(&self) -> Vec<CoreLog> {
if let Some(logs_out) = self.logs_out.as_ref() {
Expand All @@ -390,13 +390,13 @@ impl CoreTelemetry for TelemetryInstance {
///
/// See [TelemetryOptions] docs for more on configuration.
pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyhow::Error> {
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
let mut logs_out = None;

// Tracing subscriber layers =========
let mut console_pretty_layer = None;
let mut console_compact_layer = None;
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
let mut forward_layer = None;
// ===================================

Expand Down Expand Up @@ -431,14 +431,14 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho
)
}
}
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
Logger::Forward { filter } => {
let (export_layer, lo) =
CoreLogConsumerLayer::new_buffered(FORWARD_LOG_BUFFER_SIZE);
logs_out = Some(parking_lot::Mutex::new(lo));
forward_layer = Some(export_layer.with_filter(EnvFilter::new(filter)));
}
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
Logger::Push { filter, consumer } => {
forward_layer = Some(
CoreLogConsumerLayer::new(consumer).with_filter(EnvFilter::new(filter)),
Expand All @@ -448,7 +448,7 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho
let reg = tracing_subscriber::registry()
.with(console_pretty_layer)
.with(console_compact_layer);
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
let reg = reg.with(forward_layer);

Arc::new(reg) as Arc<dyn Subscriber + Send + Sync>
Expand All @@ -457,7 +457,7 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho

Ok(TelemetryInstance {
metric_prefix: opts.metric_prefix,
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
logs_out,
metrics: opts.metrics,
trace_subscriber: tracing_sub,
Expand Down
6 changes: 3 additions & 3 deletions crates/common/src/telemetry/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
time::Duration,
};

#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
pub mod core;

/// The string name (which may be prefixed) for this metric
Expand Down Expand Up @@ -377,10 +377,10 @@ pub enum MetricAttributes {
labels: Arc<OrderedPromLabelSet>,
},
/// Buffered attributes used by core-based SDKs for deferred metric initialization.
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
Buffer(core::BufferAttributes),
/// Dynamic attributes backed by a lang-side custom implementation.
#[cfg(feature = "core-based-sdk")]
#[cfg(feature = "core-telemetry-bridge")]
Dynamic(Arc<dyn core::CustomMetricAttributes>),
/// No-op attributes that store labels but do not record.
NoOp(Arc<HashMap<String, String>>),
Expand Down
21 changes: 17 additions & 4 deletions crates/sdk-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ repository = "https://github.com/temporalio/sdk-rust"
keywords = ["temporal", "workflow"]
categories = ["development-tools"]
exclude = ["machine_coverage/*"]
rust-version = "1.88.0" # due to cargo msrv find
# due to cargo msrv find
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment move as my TOML formatter claims that inline # comments should start at column 80 which looks horrible.

rust-version = "1.88.0"

[lib]

[features]
default = []
default = ["envconfig", "prometheus"]
envconfig = ["temporalio-client/envconfig", "temporalio-common/envconfig"]
prometheus = ["temporalio-common/prometheus"]
otel = [
"dep:opentelemetry",
"dep:opentelemetry_sdk",
Expand Down Expand Up @@ -95,7 +98,12 @@ tokio = { version = "1.47", default-features = false, features = [
] }
tokio-util = { version = "0.7", features = ["io", "io-util"] }
tokio-stream = { version = "0.1", default-features = false }
tonic = { workspace = true, default-features = false, features = ["tls-ring", "tls-native-roots", "transport", "codegen"] }
tonic = { workspace = true, default-features = false, features = [
"tls-ring",
"tls-native-roots",
"transport",
"codegen",
] }
tracing = "0.1"
url = "2.5"
uuid = { version = "1.18", default-features = false, features = ["v4"] }
Expand All @@ -110,11 +118,13 @@ zip = { version = "8.4", optional = true, default-features = false, features = [
[dependencies.temporalio-common]
path = "../common"
version = "0.3"
features = ["core-based-sdk", "history_builders", "test-utilities"]
default-features = false
features = ["core-telemetry-bridge", "history_builders"]

[dependencies.temporalio-client]
path = "../client"
version = "0.3"
default-features = false
features = ["core-based-sdk"]

[dependencies.temporalio-macros]
Expand All @@ -139,6 +149,9 @@ hyper-util = { version = "0.1", features = [
rstest = "0.26"
semver = "1.0"
temporalio-sdk = { path = "../sdk" }
temporalio-common = { path = "../common", version = "0.3", default-features = false, features = [
"test-utilities",
] }
tokio = { version = "1.47", default-features = false, features = [
"rt",
"rt-multi-thread",
Expand Down
10 changes: 7 additions & 3 deletions crates/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ default-features = false
[dependencies.temporalio-common]
path = "../common"
version = "0.3"
default-features = false

[dependencies.temporalio-client]
path = "../client"
version = "0.3"
default-features = false

[dependencies.temporalio-macros]
path = "../macros"
Expand All @@ -60,9 +62,11 @@ futures = "0.3"
rstest = "0.26"

[features]
default = []
antithesis_assertions = ["temporalio-sdk-core/antithesis_assertions"]
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see any real reason why this needed to be surfaced to the SDK crate.

examples = ["serde/derive", "dep:serde_json"]
default = ["envconfig", "prometheus"]
envconfig = ["temporalio-sdk-core/envconfig"]
prometheus = ["temporalio-sdk-core/prometheus"]
otel = ["temporalio-sdk-core/otel"]
examples = ["serde/derive", "dep:serde_json", "envconfig"]

[dependencies.serde_json]
version = "1"
Expand Down
16 changes: 16 additions & 0 deletions crates/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
```

## Crate Features

The SDK enables a few convenience integrations by default. Users who want a smaller dependency
graph can disable defaults and opt back into the integrations they use:

```toml
temporalio-sdk = { version = "0.3", default-features = false, features = ["envconfig"] }
```

- `envconfig` - enabled by default. Adds `ClientOptions::load_from_config` and related helpers for
loading connection settings from environment variables and `temporal.toml` files.
- `prometheus` - enabled by default. Adds the Prometheus metrics exporter in
`temporalio_common::telemetry` for serving SDK metrics from a HTTP endpoint.
- `otel` - optional. Adds the OpenTelemetry metrics exporter in `temporalio_common::telemetry` for
sending SDK metrics to an OpenTelemetry collector.

## Workflows in detail

Workflows are the core abstraction in Temporal. They are defined as structs with associated methods:
Expand Down
Loading