@temporalio/core-bridge 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +754 -473
- package/Cargo.toml +3 -3
- package/lib/index.d.ts +33 -2
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/scripts/build.js +4 -3
- package/sdk-core/.cargo/config.toml +2 -4
- package/sdk-core/.github/workflows/heavy.yml +1 -1
- package/sdk-core/.github/workflows/per-pr.yml +6 -4
- package/sdk-core/Cargo.toml +10 -3
- package/sdk-core/README.md +4 -6
- package/sdk-core/client/Cargo.toml +13 -5
- package/sdk-core/client/src/lib.rs +123 -34
- package/sdk-core/client/src/metrics.rs +70 -18
- package/sdk-core/client/src/proxy.rs +85 -0
- package/sdk-core/client/src/raw.rs +67 -5
- package/sdk-core/client/src/worker_registry/mod.rs +5 -3
- package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
- package/sdk-core/core/Cargo.toml +31 -37
- package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
- package/sdk-core/core/src/abstractions.rs +176 -108
- package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
- package/sdk-core/core/src/core_tests/determinism.rs +2 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
- package/sdk-core/core/src/core_tests/mod.rs +3 -3
- package/sdk-core/core/src/core_tests/queries.rs +42 -5
- package/sdk-core/core/src/core_tests/workers.rs +2 -3
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
- package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
- package/sdk-core/core/src/internal_flags.rs +8 -8
- package/sdk-core/core/src/lib.rs +16 -11
- package/sdk-core/core/src/pollers/mod.rs +11 -5
- package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
- package/sdk-core/core/src/protosext/mod.rs +32 -32
- package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
- package/sdk-core/core/src/retry_logic.rs +2 -2
- package/sdk-core/core/src/telemetry/log_export.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +233 -330
- package/sdk-core/core/src/telemetry/mod.rs +11 -38
- package/sdk-core/core/src/telemetry/otel.rs +355 -0
- package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
- package/sdk-core/core/src/test_help/mod.rs +80 -59
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
- package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
- package/sdk-core/core/src/worker/activities.rs +45 -46
- package/sdk-core/core/src/worker/client/mocks.rs +8 -7
- package/sdk-core/core/src/worker/client.rs +40 -39
- package/sdk-core/core/src/worker/mod.rs +72 -42
- package/sdk-core/core/src/worker/slot_provider.rs +28 -28
- package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
- package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
- package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
- package/sdk-core/core/src/worker/tuner.rs +122 -0
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
- package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
- package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
- package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
- package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
- package/sdk-core/core-api/Cargo.toml +6 -5
- package/sdk-core/core-api/src/errors.rs +8 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
- package/sdk-core/core-api/src/telemetry.rs +7 -1
- package/sdk-core/core-api/src/worker.rs +212 -56
- package/sdk-core/fsm/Cargo.toml +3 -0
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- package/sdk-core/sdk/Cargo.toml +5 -7
- package/sdk-core/sdk/src/app_data.rs +3 -3
- package/sdk-core/sdk/src/lib.rs +5 -3
- package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
- package/sdk-core/sdk/src/workflow_context.rs +10 -9
- package/sdk-core/sdk/src/workflow_future.rs +1 -1
- package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
- package/sdk-core/sdk-core-protos/build.rs +1 -10
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
- package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
- package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
- package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
- package/sdk-core/test-utils/Cargo.toml +7 -4
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +44 -62
- package/sdk-core/tests/fuzzy_workflow.rs +5 -2
- package/sdk-core/tests/heavy_tests.rs +114 -17
- package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
- package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
- package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
- package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
- package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
- package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +57 -0
- package/src/lib.rs +1 -0
- package/src/runtime.rs +51 -35
- package/ts/index.ts +67 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
- package/sdk-core/sdk/src/payload_converter.rs +0 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
- package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
- package/sdk-core/tests/wf_input_replay.rs +0 -32
|
@@ -1,37 +1,18 @@
|
|
|
1
|
-
use crate::{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
use opentelemetry::{
|
|
9
|
-
self,
|
|
10
|
-
metrics::{Meter, MeterProvider as MeterProviderT, Unit},
|
|
11
|
-
KeyValue,
|
|
12
|
-
};
|
|
13
|
-
use opentelemetry_otlp::WithExportConfig;
|
|
14
|
-
use opentelemetry_sdk::{
|
|
15
|
-
metrics::{
|
|
16
|
-
new_view,
|
|
17
|
-
reader::{AggregationSelector, DefaultAggregationSelector},
|
|
18
|
-
Aggregation, Instrument, InstrumentKind, MeterProvider, MeterProviderBuilder,
|
|
19
|
-
PeriodicReader, View,
|
|
20
|
-
},
|
|
21
|
-
runtime, AttributeSet,
|
|
1
|
+
use crate::{abstractions::dbg_panic, telemetry::TelemetryInstance};
|
|
2
|
+
|
|
3
|
+
use std::{
|
|
4
|
+
fmt::{Debug, Display},
|
|
5
|
+
iter::Iterator,
|
|
6
|
+
sync::Arc,
|
|
7
|
+
time::Duration,
|
|
22
8
|
};
|
|
23
|
-
use
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
LazyBufferInstrument, MetricAttributes, MetricCallBufferer, MetricEvent, MetricKeyValue,
|
|
29
|
-
MetricKind, MetricParameters, MetricUpdateVal, NewAttributes, NoOpCoreMeter,
|
|
30
|
-
},
|
|
31
|
-
OtelCollectorOptions, PrometheusExporterOptions,
|
|
9
|
+
use temporal_sdk_core_api::telemetry::metrics::{
|
|
10
|
+
BufferAttributes, BufferInstrumentRef, CoreMeter, Counter, Gauge, GaugeF64, Histogram,
|
|
11
|
+
HistogramDuration, HistogramF64, LazyBufferInstrument, MetricAttributes, MetricCallBufferer,
|
|
12
|
+
MetricEvent, MetricKeyValue, MetricKind, MetricParameters, MetricUpdateVal, NewAttributes,
|
|
13
|
+
NoOpCoreMeter,
|
|
32
14
|
};
|
|
33
|
-
use
|
|
34
|
-
use tonic::metadata::MetadataMap;
|
|
15
|
+
use temporal_sdk_core_protos::temporal::api::enums::v1::WorkflowTaskFailedCause;
|
|
35
16
|
|
|
36
17
|
/// Used to track context associated with metrics, and record/update them
|
|
37
18
|
///
|
|
@@ -49,21 +30,22 @@ struct Instruments {
|
|
|
49
30
|
wf_canceled_counter: Arc<dyn Counter>,
|
|
50
31
|
wf_failed_counter: Arc<dyn Counter>,
|
|
51
32
|
wf_cont_counter: Arc<dyn Counter>,
|
|
52
|
-
wf_e2e_latency: Arc<dyn
|
|
33
|
+
wf_e2e_latency: Arc<dyn HistogramDuration>,
|
|
53
34
|
wf_task_queue_poll_empty_counter: Arc<dyn Counter>,
|
|
54
35
|
wf_task_queue_poll_succeed_counter: Arc<dyn Counter>,
|
|
55
36
|
wf_task_execution_failure_counter: Arc<dyn Counter>,
|
|
56
|
-
wf_task_sched_to_start_latency: Arc<dyn
|
|
57
|
-
wf_task_replay_latency: Arc<dyn
|
|
58
|
-
wf_task_execution_latency: Arc<dyn
|
|
37
|
+
wf_task_sched_to_start_latency: Arc<dyn HistogramDuration>,
|
|
38
|
+
wf_task_replay_latency: Arc<dyn HistogramDuration>,
|
|
39
|
+
wf_task_execution_latency: Arc<dyn HistogramDuration>,
|
|
59
40
|
act_poll_no_task: Arc<dyn Counter>,
|
|
60
41
|
act_task_received_counter: Arc<dyn Counter>,
|
|
61
42
|
act_execution_failed: Arc<dyn Counter>,
|
|
62
|
-
act_sched_to_start_latency: Arc<dyn
|
|
63
|
-
act_exec_latency: Arc<dyn
|
|
43
|
+
act_sched_to_start_latency: Arc<dyn HistogramDuration>,
|
|
44
|
+
act_exec_latency: Arc<dyn HistogramDuration>,
|
|
64
45
|
worker_registered: Arc<dyn Counter>,
|
|
65
46
|
num_pollers: Arc<dyn Gauge>,
|
|
66
47
|
task_slots_available: Arc<dyn Gauge>,
|
|
48
|
+
task_slots_used: Arc<dyn Gauge>,
|
|
67
49
|
sticky_cache_hit: Arc<dyn Counter>,
|
|
68
50
|
sticky_cache_miss: Arc<dyn Counter>,
|
|
69
51
|
sticky_cache_size: Arc<dyn Gauge>,
|
|
@@ -156,30 +138,28 @@ impl MetricsContext {
|
|
|
156
138
|
|
|
157
139
|
/// Record workflow total execution time in milliseconds
|
|
158
140
|
pub(crate) fn wf_e2e_latency(&self, dur: Duration) {
|
|
159
|
-
self.instruments
|
|
160
|
-
.wf_e2e_latency
|
|
161
|
-
.record(dur.as_millis() as u64, &self.kvs);
|
|
141
|
+
self.instruments.wf_e2e_latency.record(dur, &self.kvs);
|
|
162
142
|
}
|
|
163
143
|
|
|
164
144
|
/// Record workflow task schedule to start time in millis
|
|
165
145
|
pub(crate) fn wf_task_sched_to_start_latency(&self, dur: Duration) {
|
|
166
146
|
self.instruments
|
|
167
147
|
.wf_task_sched_to_start_latency
|
|
168
|
-
.record(dur
|
|
148
|
+
.record(dur, &self.kvs);
|
|
169
149
|
}
|
|
170
150
|
|
|
171
151
|
/// Record workflow task execution time in milliseconds
|
|
172
152
|
pub(crate) fn wf_task_latency(&self, dur: Duration) {
|
|
173
153
|
self.instruments
|
|
174
154
|
.wf_task_execution_latency
|
|
175
|
-
.record(dur
|
|
155
|
+
.record(dur, &self.kvs);
|
|
176
156
|
}
|
|
177
157
|
|
|
178
158
|
/// Record time it takes to catch up on replaying a WFT
|
|
179
159
|
pub(crate) fn wf_task_replay_latency(&self, dur: Duration) {
|
|
180
160
|
self.instruments
|
|
181
161
|
.wf_task_replay_latency
|
|
182
|
-
.record(dur
|
|
162
|
+
.record(dur, &self.kvs);
|
|
183
163
|
}
|
|
184
164
|
|
|
185
165
|
/// An activity long poll timed out
|
|
@@ -201,15 +181,13 @@ impl MetricsContext {
|
|
|
201
181
|
pub(crate) fn act_sched_to_start_latency(&self, dur: Duration) {
|
|
202
182
|
self.instruments
|
|
203
183
|
.act_sched_to_start_latency
|
|
204
|
-
.record(dur
|
|
184
|
+
.record(dur, &self.kvs);
|
|
205
185
|
}
|
|
206
186
|
|
|
207
187
|
/// Record time it took to complete activity execution, from the time core generated the
|
|
208
188
|
/// activity task, to the time lang responded with a completion (failure or success).
|
|
209
189
|
pub(crate) fn act_execution_latency(&self, dur: Duration) {
|
|
210
|
-
self.instruments
|
|
211
|
-
.act_exec_latency
|
|
212
|
-
.record(dur.as_millis() as u64, &self.kvs);
|
|
190
|
+
self.instruments.act_exec_latency.record(dur, &self.kvs);
|
|
213
191
|
}
|
|
214
192
|
|
|
215
193
|
/// A worker was registered
|
|
@@ -224,6 +202,11 @@ impl MetricsContext {
|
|
|
224
202
|
.record(num as u64, &self.kvs)
|
|
225
203
|
}
|
|
226
204
|
|
|
205
|
+
/// Record current number of used task slots. Context should have worker type set.
|
|
206
|
+
pub(crate) fn task_slots_used(&self, num: u64) {
|
|
207
|
+
self.instruments.task_slots_used.record(num, &self.kvs)
|
|
208
|
+
}
|
|
209
|
+
|
|
227
210
|
/// Record current number of pollers. Context should include poller type / task queue tag.
|
|
228
211
|
pub(crate) fn record_num_pollers(&self, num: usize) {
|
|
229
212
|
self.instruments.num_pollers.record(num as u64, &self.kvs);
|
|
@@ -273,9 +256,9 @@ impl Instruments {
|
|
|
273
256
|
description: "Count of continued-as-new workflows".into(),
|
|
274
257
|
unit: "".into(),
|
|
275
258
|
}),
|
|
276
|
-
wf_e2e_latency: meter.
|
|
259
|
+
wf_e2e_latency: meter.histogram_duration(MetricParameters {
|
|
277
260
|
name: WF_E2E_LATENCY_NAME.into(),
|
|
278
|
-
unit: "
|
|
261
|
+
unit: "duration".into(),
|
|
279
262
|
description: "Histogram of total workflow execution latencies".into(),
|
|
280
263
|
}),
|
|
281
264
|
wf_task_queue_poll_empty_counter: meter.counter(MetricParameters {
|
|
@@ -293,19 +276,19 @@ impl Instruments {
|
|
|
293
276
|
description: "Count of workflow task execution failures".into(),
|
|
294
277
|
unit: "".into(),
|
|
295
278
|
}),
|
|
296
|
-
wf_task_sched_to_start_latency: meter.
|
|
279
|
+
wf_task_sched_to_start_latency: meter.histogram_duration(MetricParameters {
|
|
297
280
|
name: WF_TASK_SCHED_TO_START_LATENCY_NAME.into(),
|
|
298
|
-
unit: "
|
|
281
|
+
unit: "duration".into(),
|
|
299
282
|
description: "Histogram of workflow task schedule-to-start latencies".into(),
|
|
300
283
|
}),
|
|
301
|
-
wf_task_replay_latency: meter.
|
|
284
|
+
wf_task_replay_latency: meter.histogram_duration(MetricParameters {
|
|
302
285
|
name: WF_TASK_REPLAY_LATENCY_NAME.into(),
|
|
303
|
-
unit: "
|
|
286
|
+
unit: "duration".into(),
|
|
304
287
|
description: "Histogram of workflow task replay latencies".into(),
|
|
305
288
|
}),
|
|
306
|
-
wf_task_execution_latency: meter.
|
|
289
|
+
wf_task_execution_latency: meter.histogram_duration(MetricParameters {
|
|
307
290
|
name: WF_TASK_EXECUTION_LATENCY_NAME.into(),
|
|
308
|
-
unit: "
|
|
291
|
+
unit: "duration".into(),
|
|
309
292
|
description: "Histogram of workflow task execution (not replay) latencies".into(),
|
|
310
293
|
}),
|
|
311
294
|
act_poll_no_task: meter.counter(MetricParameters {
|
|
@@ -323,14 +306,14 @@ impl Instruments {
|
|
|
323
306
|
description: "Count of activity task execution failures".into(),
|
|
324
307
|
unit: "".into(),
|
|
325
308
|
}),
|
|
326
|
-
act_sched_to_start_latency: meter.
|
|
309
|
+
act_sched_to_start_latency: meter.histogram_duration(MetricParameters {
|
|
327
310
|
name: ACT_SCHED_TO_START_LATENCY_NAME.into(),
|
|
328
|
-
unit: "
|
|
311
|
+
unit: "duration".into(),
|
|
329
312
|
description: "Histogram of activity schedule-to-start latencies".into(),
|
|
330
313
|
}),
|
|
331
|
-
act_exec_latency: meter.
|
|
314
|
+
act_exec_latency: meter.histogram_duration(MetricParameters {
|
|
332
315
|
name: ACT_EXEC_LATENCY_NAME.into(),
|
|
333
|
-
unit: "
|
|
316
|
+
unit: "duration".into(),
|
|
334
317
|
description: "Histogram of activity execution latencies".into(),
|
|
335
318
|
}),
|
|
336
319
|
// name kept as worker start for compat with old sdk / what users expect
|
|
@@ -349,6 +332,11 @@ impl Instruments {
|
|
|
349
332
|
description: "Current number of available slots per task type".into(),
|
|
350
333
|
unit: "".into(),
|
|
351
334
|
}),
|
|
335
|
+
task_slots_used: meter.gauge(MetricParameters {
|
|
336
|
+
name: TASK_SLOTS_USED_NAME.into(),
|
|
337
|
+
description: "Current number of used slots per task type".into(),
|
|
338
|
+
unit: "".into(),
|
|
339
|
+
}),
|
|
352
340
|
sticky_cache_hit: meter.counter(MetricParameters {
|
|
353
341
|
name: "sticky_cache_hit".into(),
|
|
354
342
|
description: "Count of times the workflow cache was used for a new workflow task"
|
|
@@ -383,6 +371,7 @@ const KEY_ACT_TYPE: &str = "activity_type";
|
|
|
383
371
|
const KEY_POLLER_TYPE: &str = "poller_type";
|
|
384
372
|
const KEY_WORKER_TYPE: &str = "worker_type";
|
|
385
373
|
const KEY_EAGER: &str = "eager";
|
|
374
|
+
const KEY_TASK_FAILURE_TYPE: &str = "failure_reason";
|
|
386
375
|
|
|
387
376
|
pub(crate) fn workflow_poller() -> MetricKeyValue {
|
|
388
377
|
MetricKeyValue::new(KEY_POLLER_TYPE, "workflow_task")
|
|
@@ -414,217 +403,115 @@ pub(crate) fn local_activity_worker_type() -> MetricKeyValue {
|
|
|
414
403
|
pub(crate) fn eager(is_eager: bool) -> MetricKeyValue {
|
|
415
404
|
MetricKeyValue::new(KEY_EAGER, is_eager)
|
|
416
405
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const WF_TASK_REPLAY_LATENCY_NAME: &str = "workflow_task_replay_latency";
|
|
421
|
-
const WF_TASK_EXECUTION_LATENCY_NAME: &str = "workflow_task_execution_latency";
|
|
422
|
-
const ACT_SCHED_TO_START_LATENCY_NAME: &str = "activity_schedule_to_start_latency";
|
|
423
|
-
const ACT_EXEC_LATENCY_NAME: &str = "activity_execution_latency";
|
|
424
|
-
const NUM_POLLERS_NAME: &str = "num_pollers";
|
|
425
|
-
const TASK_SLOTS_AVAILABLE_NAME: &str = "worker_task_slots_available";
|
|
426
|
-
const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size";
|
|
427
|
-
|
|
428
|
-
/// Artisanal, handcrafted latency buckets for workflow e2e latency which should expose a useful
|
|
429
|
-
/// set of buckets for < 1 day runtime workflows. Beyond that, this metric probably isn't very
|
|
430
|
-
/// helpful
|
|
431
|
-
static WF_LATENCY_MS_BUCKETS: &[f64] = &[
|
|
432
|
-
100.,
|
|
433
|
-
500.,
|
|
434
|
-
1000.,
|
|
435
|
-
1500.,
|
|
436
|
-
2000.,
|
|
437
|
-
5000.,
|
|
438
|
-
10_000.,
|
|
439
|
-
30_000.,
|
|
440
|
-
60_000.,
|
|
441
|
-
120_000.,
|
|
442
|
-
300_000.,
|
|
443
|
-
600_000.,
|
|
444
|
-
1_800_000., // 30 min
|
|
445
|
-
3_600_000., // 1 hr
|
|
446
|
-
30_600_000., // 10 hrs
|
|
447
|
-
8.64e7, // 24 hrs
|
|
448
|
-
];
|
|
449
|
-
|
|
450
|
-
/// Task latencies are expected to be fast, no longer than a second which was generally the deadlock
|
|
451
|
-
/// timeout in old SDKs. Here it's a bit different since a WFT may represent multiple activations.
|
|
452
|
-
static WF_TASK_MS_BUCKETS: &[f64] = &[1., 10., 20., 50., 100., 200., 500., 1000.];
|
|
453
|
-
|
|
454
|
-
/// Activity are generally expected to take at least a little time, and sometimes quite a while,
|
|
455
|
-
/// since they're doing side-effecty things, etc.
|
|
456
|
-
static ACT_EXE_MS_BUCKETS: &[f64] = &[50., 100., 500., 1000., 5000., 10_000., 60_000.];
|
|
457
|
-
|
|
458
|
-
/// Schedule-to-start latency buckets for both WFT and AT
|
|
459
|
-
static TASK_SCHED_TO_START_MS_BUCKETS: &[f64] =
|
|
460
|
-
&[100., 500., 1000., 5000., 10_000., 100_000., 1_000_000.];
|
|
461
|
-
|
|
462
|
-
/// Default buckets. Should never really be used as they will be meaningless for many things, but
|
|
463
|
-
/// broadly it's trying to represent latencies in millis.
|
|
464
|
-
pub(super) static DEFAULT_MS_BUCKETS: &[f64] = &[50., 100., 500., 1000., 2500., 10_000.];
|
|
465
|
-
|
|
466
|
-
/// Returns the default histogram buckets that lang should use for a given metric name if they
|
|
467
|
-
/// have not been overridden by the user.
|
|
468
|
-
///
|
|
469
|
-
/// The name must *not* be prefixed with `temporal_`
|
|
470
|
-
pub fn default_buckets_for(histo_name: &str) -> &'static [f64] {
|
|
471
|
-
match histo_name {
|
|
472
|
-
WF_E2E_LATENCY_NAME => WF_LATENCY_MS_BUCKETS,
|
|
473
|
-
WF_TASK_EXECUTION_LATENCY_NAME | WF_TASK_REPLAY_LATENCY_NAME => WF_TASK_MS_BUCKETS,
|
|
474
|
-
WF_TASK_SCHED_TO_START_LATENCY_NAME | ACT_SCHED_TO_START_LATENCY_NAME => {
|
|
475
|
-
TASK_SCHED_TO_START_MS_BUCKETS
|
|
476
|
-
}
|
|
477
|
-
ACT_EXEC_LATENCY_NAME => ACT_EXE_MS_BUCKETS,
|
|
478
|
-
_ => DEFAULT_MS_BUCKETS,
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/// Chooses appropriate aggregators for our metrics
|
|
483
|
-
#[derive(Debug, Clone, Default)]
|
|
484
|
-
pub struct SDKAggSelector {
|
|
485
|
-
default: DefaultAggregationSelector,
|
|
406
|
+
pub(crate) enum FailureReason {
|
|
407
|
+
Nondeterminism,
|
|
408
|
+
Workflow,
|
|
486
409
|
}
|
|
487
|
-
impl
|
|
488
|
-
fn
|
|
489
|
-
match
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
_ => self.default.aggregation(kind),
|
|
495
|
-
}
|
|
410
|
+
impl Display for FailureReason {
|
|
411
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
412
|
+
let str = match self {
|
|
413
|
+
FailureReason::Nondeterminism => "NonDeterminismError",
|
|
414
|
+
FailureReason::Workflow => "WorkflowError",
|
|
415
|
+
};
|
|
416
|
+
write!(f, "{}", str)
|
|
496
417
|
}
|
|
497
418
|
}
|
|
498
|
-
|
|
499
|
-
fn
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
new_view(
|
|
504
|
-
Instrument::new().name(format!("*{metric_name}")),
|
|
505
|
-
opentelemetry_sdk::metrics::Stream::new().aggregation(
|
|
506
|
-
Aggregation::ExplicitBucketHistogram {
|
|
507
|
-
boundaries: buckets.to_vec(),
|
|
508
|
-
record_min_max: true,
|
|
509
|
-
},
|
|
510
|
-
),
|
|
511
|
-
)
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
pub(super) fn augment_meter_provider_with_defaults(
|
|
515
|
-
mpb: MeterProviderBuilder,
|
|
516
|
-
global_tags: &HashMap<String, String>,
|
|
517
|
-
) -> opentelemetry::metrics::Result<MeterProviderBuilder> {
|
|
518
|
-
// Some histograms are actually gauges, but we have to use histograms otherwise they forget
|
|
519
|
-
// their value between collections since we don't use callbacks.
|
|
520
|
-
Ok(mpb
|
|
521
|
-
.with_view(histo_view(WF_E2E_LATENCY_NAME, WF_LATENCY_MS_BUCKETS)?)
|
|
522
|
-
.with_view(histo_view(
|
|
523
|
-
WF_TASK_EXECUTION_LATENCY_NAME,
|
|
524
|
-
WF_TASK_MS_BUCKETS,
|
|
525
|
-
)?)
|
|
526
|
-
.with_view(histo_view(WF_TASK_REPLAY_LATENCY_NAME, WF_TASK_MS_BUCKETS)?)
|
|
527
|
-
.with_view(histo_view(
|
|
528
|
-
WF_TASK_SCHED_TO_START_LATENCY_NAME,
|
|
529
|
-
TASK_SCHED_TO_START_MS_BUCKETS,
|
|
530
|
-
)?)
|
|
531
|
-
.with_view(histo_view(
|
|
532
|
-
ACT_SCHED_TO_START_LATENCY_NAME,
|
|
533
|
-
TASK_SCHED_TO_START_MS_BUCKETS,
|
|
534
|
-
)?)
|
|
535
|
-
.with_view(histo_view(ACT_EXEC_LATENCY_NAME, ACT_EXE_MS_BUCKETS)?)
|
|
536
|
-
.with_resource(default_resource(global_tags)))
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/// OTel has no built-in synchronous Gauge. Histograms used to be able to serve that purpose, but
|
|
540
|
-
/// they broke that. Lovely. So, we need to implement one by hand.
|
|
541
|
-
pub(crate) struct MemoryGaugeU64 {
|
|
542
|
-
labels_to_values: Arc<RwLock<HashMap<AttributeSet, u64>>>,
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
impl MemoryGaugeU64 {
|
|
546
|
-
fn new(params: MetricParameters, meter: &Meter) -> Self {
|
|
547
|
-
let gauge = meter
|
|
548
|
-
.u64_observable_gauge(params.name)
|
|
549
|
-
.with_unit(Unit::new(params.unit))
|
|
550
|
-
.with_description(params.description)
|
|
551
|
-
.init();
|
|
552
|
-
let map = Arc::new(RwLock::new(HashMap::<AttributeSet, u64>::new()));
|
|
553
|
-
let map_c = map.clone();
|
|
554
|
-
meter
|
|
555
|
-
.register_callback(&[gauge.as_any()], move |o| {
|
|
556
|
-
// This whole thing is... extra stupid.
|
|
557
|
-
// See https://github.com/open-telemetry/opentelemetry-rust/issues/1181
|
|
558
|
-
// The performance is likely bad here, but, given this is only called when metrics
|
|
559
|
-
// are exported it should be livable for now.
|
|
560
|
-
let map_rlock = map_c.read();
|
|
561
|
-
for (kvs, val) in map_rlock.iter() {
|
|
562
|
-
let kvs: Vec<_> = kvs
|
|
563
|
-
.iter()
|
|
564
|
-
.map(|(k, v)| KeyValue::new(k.clone(), v.clone()))
|
|
565
|
-
.collect();
|
|
566
|
-
o.observe_u64(&gauge, *val, kvs.as_slice())
|
|
567
|
-
}
|
|
568
|
-
})
|
|
569
|
-
.expect("instrument must exist we just created it");
|
|
570
|
-
MemoryGaugeU64 {
|
|
571
|
-
labels_to_values: map,
|
|
419
|
+
impl From<WorkflowTaskFailedCause> for FailureReason {
|
|
420
|
+
fn from(v: WorkflowTaskFailedCause) -> Self {
|
|
421
|
+
match v {
|
|
422
|
+
WorkflowTaskFailedCause::NonDeterministicError => FailureReason::Nondeterminism,
|
|
423
|
+
_ => FailureReason::Workflow,
|
|
572
424
|
}
|
|
573
425
|
}
|
|
574
|
-
fn record(&self, val: u64, kvs: &[KeyValue]) {
|
|
575
|
-
self.labels_to_values
|
|
576
|
-
.write()
|
|
577
|
-
.insert(AttributeSet::from(kvs), val);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
/// Create an OTel meter that can be used as a [CoreMeter] to export metrics over OTLP.
|
|
582
|
-
pub fn build_otlp_metric_exporter(
|
|
583
|
-
opts: OtelCollectorOptions,
|
|
584
|
-
) -> Result<CoreOtelMeter, anyhow::Error> {
|
|
585
|
-
let exporter = opentelemetry_otlp::TonicExporterBuilder::default()
|
|
586
|
-
.with_endpoint(opts.url.to_string())
|
|
587
|
-
.with_metadata(MetadataMap::from_headers((&opts.headers).try_into()?))
|
|
588
|
-
.build_metrics_exporter(
|
|
589
|
-
Box::<SDKAggSelector>::default(),
|
|
590
|
-
Box::new(metric_temporality_to_selector(opts.metric_temporality)),
|
|
591
|
-
)?;
|
|
592
|
-
let reader = PeriodicReader::builder(exporter, runtime::Tokio)
|
|
593
|
-
.with_interval(opts.metric_periodicity)
|
|
594
|
-
.build();
|
|
595
|
-
let mp = augment_meter_provider_with_defaults(
|
|
596
|
-
MeterProvider::builder().with_reader(reader),
|
|
597
|
-
&opts.global_tags,
|
|
598
|
-
)?
|
|
599
|
-
.build();
|
|
600
|
-
Ok::<_, anyhow::Error>(CoreOtelMeter(mp.meter(TELEM_SERVICE_NAME)))
|
|
601
426
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
427
|
+
pub(crate) fn failure_reason(reason: FailureReason) -> MetricKeyValue {
|
|
428
|
+
MetricKeyValue::new(KEY_TASK_FAILURE_TYPE, reason.to_string())
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
pub(super) const WF_E2E_LATENCY_NAME: &str = "workflow_endtoend_latency";
|
|
432
|
+
pub(super) const WF_TASK_SCHED_TO_START_LATENCY_NAME: &str =
|
|
433
|
+
"workflow_task_schedule_to_start_latency";
|
|
434
|
+
pub(super) const WF_TASK_REPLAY_LATENCY_NAME: &str = "workflow_task_replay_latency";
|
|
435
|
+
pub(super) const WF_TASK_EXECUTION_LATENCY_NAME: &str = "workflow_task_execution_latency";
|
|
436
|
+
pub(super) const ACT_SCHED_TO_START_LATENCY_NAME: &str = "activity_schedule_to_start_latency";
|
|
437
|
+
pub(super) const ACT_EXEC_LATENCY_NAME: &str = "activity_execution_latency";
|
|
438
|
+
pub(super) const NUM_POLLERS_NAME: &str = "num_pollers";
|
|
439
|
+
pub(super) const TASK_SLOTS_AVAILABLE_NAME: &str = "worker_task_slots_available";
|
|
440
|
+
pub(super) const TASK_SLOTS_USED_NAME: &str = "worker_task_slots_used";
|
|
441
|
+
pub(super) const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size";
|
|
442
|
+
|
|
443
|
+
/// Helps define buckets once in terms of millis, but also generates a seconds version
|
|
444
|
+
macro_rules! define_latency_buckets {
|
|
445
|
+
($(($metric_name:pat, $name:ident, $sec_name:ident, [$($bucket:expr),*])),*) => {
|
|
446
|
+
$(
|
|
447
|
+
pub(super) static $name: &[f64] = &[$($bucket,)*];
|
|
448
|
+
pub(super) static $sec_name: &[f64] = &[$( $bucket / 1000.0, )*];
|
|
449
|
+
)*
|
|
450
|
+
|
|
451
|
+
/// Returns the default histogram buckets that lang should use for a given metric name if
|
|
452
|
+
/// they have not been overridden by the user. If `use_seconds` is true, returns buckets
|
|
453
|
+
/// in terms of seconds rather than milliseconds.
|
|
454
|
+
///
|
|
455
|
+
/// The name must *not* be prefixed with `temporal_`
|
|
456
|
+
pub fn default_buckets_for(histo_name: &str, use_seconds: bool) -> &'static [f64] {
|
|
457
|
+
match histo_name {
|
|
458
|
+
$(
|
|
459
|
+
$metric_name => { if use_seconds { &$sec_name } else { &$name } },
|
|
460
|
+
)*
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
};
|
|
607
464
|
}
|
|
608
465
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
466
|
+
define_latency_buckets!(
|
|
467
|
+
(
|
|
468
|
+
WF_E2E_LATENCY_NAME,
|
|
469
|
+
WF_LATENCY_MS_BUCKETS,
|
|
470
|
+
WF_LATENCY_S_BUCKETS,
|
|
471
|
+
[
|
|
472
|
+
100.,
|
|
473
|
+
500.,
|
|
474
|
+
1000.,
|
|
475
|
+
1500.,
|
|
476
|
+
2000.,
|
|
477
|
+
5000.,
|
|
478
|
+
10_000.,
|
|
479
|
+
30_000.,
|
|
480
|
+
60_000.,
|
|
481
|
+
120_000.,
|
|
482
|
+
300_000.,
|
|
483
|
+
600_000.,
|
|
484
|
+
1_800_000., // 30 min
|
|
485
|
+
3_600_000., // 1 hr
|
|
486
|
+
30_600_000., // 10 hrs
|
|
487
|
+
8.64e7 // 24 hrs
|
|
488
|
+
]
|
|
489
|
+
),
|
|
490
|
+
(
|
|
491
|
+
WF_TASK_EXECUTION_LATENCY_NAME | WF_TASK_REPLAY_LATENCY_NAME,
|
|
492
|
+
WF_TASK_MS_BUCKETS,
|
|
493
|
+
WF_TASK_S_BUCKETS,
|
|
494
|
+
[1., 10., 20., 50., 100., 200., 500., 1000.]
|
|
495
|
+
),
|
|
496
|
+
(
|
|
497
|
+
ACT_EXEC_LATENCY_NAME,
|
|
498
|
+
ACT_EXE_MS_BUCKETS,
|
|
499
|
+
ACT_EXE_S_BUCKETS,
|
|
500
|
+
[50., 100., 500., 1000., 5000., 10_000., 60_000.]
|
|
501
|
+
),
|
|
502
|
+
(
|
|
503
|
+
WF_TASK_SCHED_TO_START_LATENCY_NAME | ACT_SCHED_TO_START_LATENCY_NAME,
|
|
504
|
+
TASK_SCHED_TO_START_MS_BUCKETS,
|
|
505
|
+
TASK_SCHED_TO_START_S_BUCKETS,
|
|
506
|
+
[100., 500., 1000., 5000., 10_000., 100_000., 1_000_000.]
|
|
507
|
+
),
|
|
508
|
+
(
|
|
509
|
+
_,
|
|
510
|
+
DEFAULT_MS_BUCKETS,
|
|
511
|
+
DEFAULT_S_BUCKETS,
|
|
512
|
+
[50., 100., 500., 1000., 2500., 10_000.]
|
|
513
|
+
)
|
|
514
|
+
);
|
|
628
515
|
|
|
629
516
|
/// Buffers [MetricEvent]s for periodic consumption by lang
|
|
630
517
|
#[derive(Debug)]
|
|
@@ -668,7 +555,6 @@ where
|
|
|
668
555
|
populate_into: hole.clone(),
|
|
669
556
|
});
|
|
670
557
|
BufferInstrument {
|
|
671
|
-
kind,
|
|
672
558
|
instrument_ref: hole,
|
|
673
559
|
tx: self.calls_tx.clone(),
|
|
674
560
|
}
|
|
@@ -716,9 +602,21 @@ where
|
|
|
716
602
|
Arc::new(self.new_instrument(params, MetricKind::Histogram))
|
|
717
603
|
}
|
|
718
604
|
|
|
605
|
+
fn histogram_f64(&self, params: MetricParameters) -> Arc<dyn HistogramF64> {
|
|
606
|
+
Arc::new(self.new_instrument(params, MetricKind::HistogramF64))
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
fn histogram_duration(&self, params: MetricParameters) -> Arc<dyn HistogramDuration> {
|
|
610
|
+
Arc::new(self.new_instrument(params, MetricKind::HistogramDuration))
|
|
611
|
+
}
|
|
612
|
+
|
|
719
613
|
fn gauge(&self, params: MetricParameters) -> Arc<dyn Gauge> {
|
|
720
614
|
Arc::new(self.new_instrument(params, MetricKind::Gauge))
|
|
721
615
|
}
|
|
616
|
+
|
|
617
|
+
fn gauge_f64(&self, params: MetricParameters) -> Arc<dyn GaugeF64> {
|
|
618
|
+
Arc::new(self.new_instrument(params, MetricKind::GaugeF64))
|
|
619
|
+
}
|
|
722
620
|
}
|
|
723
621
|
impl<I> MetricCallBufferer<I> for MetricsCallBuffer<I>
|
|
724
622
|
where
|
|
@@ -730,7 +628,6 @@ where
|
|
|
730
628
|
}
|
|
731
629
|
|
|
732
630
|
struct BufferInstrument<I: BufferInstrumentRef> {
|
|
733
|
-
kind: MetricKind,
|
|
734
631
|
instrument_ref: LazyBufferInstrument<I>,
|
|
735
632
|
tx: LogErrOnFullSender<MetricEvent<I>>,
|
|
736
633
|
}
|
|
@@ -738,17 +635,14 @@ impl<I> BufferInstrument<I>
|
|
|
738
635
|
where
|
|
739
636
|
I: Clone + BufferInstrumentRef,
|
|
740
637
|
{
|
|
741
|
-
fn send(&self, value:
|
|
638
|
+
fn send(&self, value: MetricUpdateVal, attributes: &MetricAttributes) {
|
|
742
639
|
let attributes = match attributes {
|
|
743
640
|
MetricAttributes::Buffer(l) => l.clone(),
|
|
744
641
|
_ => panic!("MetricsCallBuffer only works with MetricAttributes::Lang"),
|
|
745
642
|
};
|
|
746
643
|
self.tx.send(MetricEvent::Update {
|
|
747
644
|
instrument: self.instrument_ref.clone(),
|
|
748
|
-
update:
|
|
749
|
-
MetricKind::Counter => MetricUpdateVal::Delta(value),
|
|
750
|
-
MetricKind::Gauge | MetricKind::Histogram => MetricUpdateVal::Value(value),
|
|
751
|
-
},
|
|
645
|
+
update: value,
|
|
752
646
|
attributes: attributes.clone(),
|
|
753
647
|
});
|
|
754
648
|
}
|
|
@@ -758,7 +652,7 @@ where
|
|
|
758
652
|
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
759
653
|
{
|
|
760
654
|
fn add(&self, value: u64, attributes: &MetricAttributes) {
|
|
761
|
-
self.send(value, attributes)
|
|
655
|
+
self.send(MetricUpdateVal::Delta(value), attributes)
|
|
762
656
|
}
|
|
763
657
|
}
|
|
764
658
|
impl<I> Gauge for BufferInstrument<I>
|
|
@@ -766,7 +660,15 @@ where
|
|
|
766
660
|
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
767
661
|
{
|
|
768
662
|
fn record(&self, value: u64, attributes: &MetricAttributes) {
|
|
769
|
-
self.send(value, attributes)
|
|
663
|
+
self.send(MetricUpdateVal::Value(value), attributes)
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
impl<I> GaugeF64 for BufferInstrument<I>
|
|
667
|
+
where
|
|
668
|
+
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
669
|
+
{
|
|
670
|
+
fn record(&self, value: f64, attributes: &MetricAttributes) {
|
|
671
|
+
self.send(MetricUpdateVal::ValueF64(value), attributes)
|
|
770
672
|
}
|
|
771
673
|
}
|
|
772
674
|
impl<I> Histogram for BufferInstrument<I>
|
|
@@ -774,65 +676,23 @@ where
|
|
|
774
676
|
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
775
677
|
{
|
|
776
678
|
fn record(&self, value: u64, attributes: &MetricAttributes) {
|
|
777
|
-
self.send(value, attributes)
|
|
679
|
+
self.send(MetricUpdateVal::Value(value), attributes)
|
|
778
680
|
}
|
|
779
681
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
fn
|
|
785
|
-
|
|
786
|
-
kvs: Arc::new(attribs.attributes.into_iter().map(KeyValue::from).collect()),
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
fn extend_attributes(
|
|
791
|
-
&self,
|
|
792
|
-
existing: MetricAttributes,
|
|
793
|
-
attribs: NewAttributes,
|
|
794
|
-
) -> MetricAttributes {
|
|
795
|
-
if let MetricAttributes::OTel { mut kvs } = existing {
|
|
796
|
-
Arc::make_mut(&mut kvs).extend(attribs.attributes.into_iter().map(Into::into));
|
|
797
|
-
MetricAttributes::OTel { kvs }
|
|
798
|
-
} else {
|
|
799
|
-
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
800
|
-
existing
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
fn counter(&self, params: MetricParameters) -> Arc<dyn Counter> {
|
|
805
|
-
Arc::new(
|
|
806
|
-
self.0
|
|
807
|
-
.u64_counter(params.name)
|
|
808
|
-
.with_unit(Unit::new(params.unit))
|
|
809
|
-
.with_description(params.description)
|
|
810
|
-
.init(),
|
|
811
|
-
)
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
fn histogram(&self, params: MetricParameters) -> Arc<dyn Histogram> {
|
|
815
|
-
Arc::new(
|
|
816
|
-
self.0
|
|
817
|
-
.u64_histogram(params.name)
|
|
818
|
-
.with_unit(Unit::new(params.unit))
|
|
819
|
-
.with_description(params.description)
|
|
820
|
-
.init(),
|
|
821
|
-
)
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
fn gauge(&self, params: MetricParameters) -> Arc<dyn Gauge> {
|
|
825
|
-
Arc::new(MemoryGaugeU64::new(params, &self.0))
|
|
682
|
+
impl<I> HistogramF64 for BufferInstrument<I>
|
|
683
|
+
where
|
|
684
|
+
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
685
|
+
{
|
|
686
|
+
fn record(&self, value: f64, attributes: &MetricAttributes) {
|
|
687
|
+
self.send(MetricUpdateVal::ValueF64(value), attributes)
|
|
826
688
|
}
|
|
827
689
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
835
|
-
}
|
|
690
|
+
impl<I> HistogramDuration for BufferInstrument<I>
|
|
691
|
+
where
|
|
692
|
+
I: BufferInstrumentRef + Send + Sync + Clone,
|
|
693
|
+
{
|
|
694
|
+
fn record(&self, value: Duration, attributes: &MetricAttributes) {
|
|
695
|
+
self.send(MetricUpdateVal::Duration(value), attributes)
|
|
836
696
|
}
|
|
837
697
|
}
|
|
838
698
|
|
|
@@ -864,10 +724,25 @@ impl<CM: CoreMeter> CoreMeter for PrefixedMetricsMeter<CM> {
|
|
|
864
724
|
self.meter.histogram(params)
|
|
865
725
|
}
|
|
866
726
|
|
|
727
|
+
fn histogram_f64(&self, mut params: MetricParameters) -> Arc<dyn HistogramF64> {
|
|
728
|
+
params.name = (self.prefix.clone() + &*params.name).into();
|
|
729
|
+
self.meter.histogram_f64(params)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
fn histogram_duration(&self, mut params: MetricParameters) -> Arc<dyn HistogramDuration> {
|
|
733
|
+
params.name = (self.prefix.clone() + &*params.name).into();
|
|
734
|
+
self.meter.histogram_duration(params)
|
|
735
|
+
}
|
|
736
|
+
|
|
867
737
|
fn gauge(&self, mut params: MetricParameters) -> Arc<dyn Gauge> {
|
|
868
738
|
params.name = (self.prefix.clone() + &*params.name).into();
|
|
869
739
|
self.meter.gauge(params)
|
|
870
740
|
}
|
|
741
|
+
|
|
742
|
+
fn gauge_f64(&self, mut params: MetricParameters) -> Arc<dyn GaugeF64> {
|
|
743
|
+
params.name = (self.prefix.clone() + &*params.name).into();
|
|
744
|
+
self.meter.gauge_f64(params)
|
|
745
|
+
}
|
|
871
746
|
}
|
|
872
747
|
|
|
873
748
|
#[cfg(test)]
|
|
@@ -932,7 +807,7 @@ mod tests {
|
|
|
932
807
|
a1.set(Arc::new(DummyCustomAttrs(1))).unwrap();
|
|
933
808
|
// Verify all metrics are created. This number will need to get updated any time a metric
|
|
934
809
|
// is added.
|
|
935
|
-
let num_metrics =
|
|
810
|
+
let num_metrics = 24;
|
|
936
811
|
#[allow(clippy::needless_range_loop)] // Sorry clippy, this reads easier.
|
|
937
812
|
for metric_num in 1..=num_metrics {
|
|
938
813
|
let hole = assert_matches!(&events[metric_num],
|
|
@@ -970,9 +845,10 @@ mod tests {
|
|
|
970
845
|
MetricEvent::Update {
|
|
971
846
|
instrument,
|
|
972
847
|
attributes,
|
|
973
|
-
update: MetricUpdateVal::
|
|
848
|
+
update: MetricUpdateVal::Duration(d)
|
|
974
849
|
}
|
|
975
850
|
if DummyCustomAttrs::as_id(attributes) == 2 && instrument.get().0 == 11
|
|
851
|
+
&& d == &Duration::from_secs(1)
|
|
976
852
|
);
|
|
977
853
|
}
|
|
978
854
|
|
|
@@ -994,6 +870,11 @@ mod tests {
|
|
|
994
870
|
description: "a counter".into(),
|
|
995
871
|
unit: "bleezles".into(),
|
|
996
872
|
});
|
|
873
|
+
let histo_dur = call_buffer.histogram_duration(MetricParameters {
|
|
874
|
+
name: "histo_dur".into(),
|
|
875
|
+
description: "a duration histogram".into(),
|
|
876
|
+
unit: "seconds".into(),
|
|
877
|
+
});
|
|
997
878
|
let attrs_1 = call_buffer.new_attributes(NewAttributes {
|
|
998
879
|
attributes: vec![MetricKeyValue::new("hi", "yo")],
|
|
999
880
|
});
|
|
@@ -1003,6 +884,7 @@ mod tests {
|
|
|
1003
884
|
ctr.add(1, &attrs_1);
|
|
1004
885
|
histo.record(2, &attrs_1);
|
|
1005
886
|
gauge.record(3, &attrs_2);
|
|
887
|
+
histo_dur.record(Duration::from_secs_f64(1.2), &attrs_1);
|
|
1006
888
|
|
|
1007
889
|
let mut calls = call_buffer.retrieve();
|
|
1008
890
|
calls.reverse();
|
|
@@ -1039,6 +921,17 @@ mod tests {
|
|
|
1039
921
|
=> populate_into
|
|
1040
922
|
);
|
|
1041
923
|
gauge_3.set(Arc::new(DummyInstrumentRef(3))).unwrap();
|
|
924
|
+
let hist_4 = assert_matches!(
|
|
925
|
+
calls.pop(),
|
|
926
|
+
Some(MetricEvent::Create {
|
|
927
|
+
params,
|
|
928
|
+
populate_into,
|
|
929
|
+
kind: MetricKind::HistogramDuration
|
|
930
|
+
})
|
|
931
|
+
if params.name == "histo_dur"
|
|
932
|
+
=> populate_into
|
|
933
|
+
);
|
|
934
|
+
hist_4.set(Arc::new(DummyInstrumentRef(4))).unwrap();
|
|
1042
935
|
let a1 = assert_matches!(
|
|
1043
936
|
calls.pop(),
|
|
1044
937
|
Some(MetricEvent::CreateAttributes {
|
|
@@ -1086,7 +979,17 @@ mod tests {
|
|
|
1086
979
|
attributes,
|
|
1087
980
|
update: MetricUpdateVal::Value(3)
|
|
1088
981
|
})
|
|
1089
|
-
if DummyCustomAttrs::as_id(&attributes) == 2&& instrument.get().0 == 3
|
|
982
|
+
if DummyCustomAttrs::as_id(&attributes) == 2 && instrument.get().0 == 3
|
|
983
|
+
);
|
|
984
|
+
assert_matches!(
|
|
985
|
+
calls.pop(),
|
|
986
|
+
Some(MetricEvent::Update{
|
|
987
|
+
instrument,
|
|
988
|
+
attributes,
|
|
989
|
+
update: MetricUpdateVal::Duration(d)
|
|
990
|
+
})
|
|
991
|
+
if DummyCustomAttrs::as_id(&attributes) == 1 && instrument.get().0 == 4
|
|
992
|
+
&& d == Duration::from_secs_f64(1.2)
|
|
1090
993
|
);
|
|
1091
994
|
}
|
|
1092
995
|
}
|