Skip to content

Update temporal integration to support temporal version 1.27 #20142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0fbb431
update temporal integration to support temporal version 1.27
phuongdnguyen Apr 24, 2025
437feca
fix failed ci job
phuongdnguyen Apr 24, 2025
576eb56
fix the lint error
phuongdnguyen May 4, 2025
b5a68d1
update script to generate temporal metric
phuongdnguyen May 4, 2025
e751019
sort temporal metrics
phuongdnguyen May 4, 2025
4f8cafe
run black format
phuongdnguyen May 7, 2025
6565fbe
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 7, 2025
72ee22f
Merge branch 'DataDog:master' into update-temporal-integration
phuongdnguyen May 13, 2025
47c9fbc
remove outdated metrics
May 13, 2025
46139b8
update temporal test
May 14, 2025
48245f1
Merge branch 'DataDog:master' into update-temporal-integration
phuongdnguyen May 14, 2025
4d70b3e
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 14, 2025
dca8c3d
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 15, 2025
de27fb7
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 16, 2025
9d57916
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 17, 2025
db21635
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 19, 2025
16cace0
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 19, 2025
5b21db6
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 20, 2025
2a14153
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 21, 2025
1699aa5
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 26, 2025
193f06e
Merge branch 'master' into update-temporal-integration
phuongdnguyen May 29, 2025
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 temporal/changelog.d/20142.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update temporal integration to support temporal version 1.27
395 changes: 246 additions & 149 deletions temporal/datadog_checks/temporal/metrics.py

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions temporal/hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

[[envs.default.matrix]]
python = ["3.12"]
version = ["1.19"]
version = ["1.27"]

[envs.default.overrides]
matrix.version.env-vars = [
{ key = "TEMPORAL_VERSION", value = "1.19.1", if = ["1.19"] },
{ key = "TEMPORAL_VERSION", value = "1.27.0", if = ["1.27"] },
]
1,330 changes: 711 additions & 619 deletions temporal/metadata.csv

Large diffs are not rendered by default.

94 changes: 63 additions & 31 deletions temporal/scripts/generate_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,67 +19,65 @@

def main():
# First, read the existing metadata.csv to keep existing metadata from metrics for later
with open('metadata.csv', newline='') as metadata_file:
with open("metadata.csv", newline="") as metadata_file:
reader = csv.DictReader(metadata_file)
metadata_fields = reader.fieldnames
previous_metadata = {row['metric_name']: row for row in reader}
previous_metadata = {row["metric_name"]: row for row in reader}

# Then, read metrics from temporal's source code, fed through stdin
# This file lives in /common/metrics/metric_defs.go inside temporal's repo
parsed_metrics = (parse_temporal_metric(line) for line in sys.stdin.readlines())
temporal_metric_types = {metric['name']: metric['type'] for metric in parsed_metrics if metric}

temporal_metric_types = extract_metric_defs(sys.stdin.read())
# Sanity check: Check whether there are metrics in the temporal code that are not present
# in the `METRIC_MAP` and warn about them:
missing_metrics = set(temporal_metric_types) - set(METRIC_MAP)
if missing_metrics:
print("WARNING: the input code contains metrics not defined in `METRIC_MAP`:")
print('\n'.join(f"- {metric}" for metric in missing_metrics))
print("\n".join(f"- {metric}" for metric in missing_metrics))

# Merge all the data
metadata = []

def append_metric_metadata(metric_name, metric_type='count', unit_name=None):
qualified_metric_name = f'temporal.server.{metric_name}'
metric_meta = {k: '' for k in metadata_fields}
metric_meta['orientation'] = 0
def append_metric_metadata(metric_name, metric_type="count", unit_name=None):
qualified_metric_name = f"temporal.server.{metric_name}"
metric_meta = {k: "" for k in metadata_fields}
metric_meta["orientation"] = 0
metric_meta.update(previous_metadata.get(qualified_metric_name, {}))
metric_meta['integration'] = 'temporal'
metric_meta['metric_name'] = qualified_metric_name
metric_meta['metric_type'] = metric_type
metric_meta['short_name'] = metric_name.replace('.', ' ').replace('_', ' ')
metric_meta["integration"] = "temporal"
metric_meta["metric_name"] = qualified_metric_name
metric_meta["metric_type"] = metric_type
metric_meta["short_name"] = metric_name.replace(".", " ").replace("_", " ")
# Only override unit_name explicitly
if unit_name is not None:
metric_meta['unit_name'] = unit_name
metric_meta["unit_name"] = unit_name
metadata.append(metric_meta)

for temporal_name, name in METRIC_MAP.items():
try:
temporal_type = temporal_metric_types[temporal_name]
except KeyError:
print(f"WARNING: skipping metric `{temporal_name}/{name}` as it's not present in input data")
print(f"WARNING: skipping metric `{temporal_name}` as it's not present in input data")
continue

if temporal_type == 'counter':
append_metric_metadata(f'{name}.count')
elif temporal_type == 'gauge':
append_metric_metadata(name, 'gauge')
elif temporal_type.endswith('histogram'):
if temporal_type == "counter":
append_metric_metadata(f"{name}.count")
elif temporal_type == "gauge":
append_metric_metadata(name, "gauge")
elif temporal_type.endswith("histogram"):
unit_name = None
if temporal_type == 'byteshistogram':
if temporal_type == "byteshistogram":
unit_name = "byte"
append_metric_metadata(f'{name}.bucket')
append_metric_metadata(f'{name}.count')
append_metric_metadata(f'{name}.sum', unit_name=unit_name)
elif temporal_type == 'timer':
append_metric_metadata(f'{name}.bucket')
append_metric_metadata(f'{name}.count')
append_metric_metadata(f'{name}.sum', unit_name='millisecond')
append_metric_metadata(f"{name}.bucket")
append_metric_metadata(f"{name}.count")
append_metric_metadata(f"{name}.sum", unit_name=unit_name)
elif temporal_type == "timer":
append_metric_metadata(f"{name}.bucket")
append_metric_metadata(f"{name}.count")
append_metric_metadata(f"{name}.sum", unit_name="millisecond")
else:
print(f"Unrecognized metric type {temporal_type}, skipping.")

# Write everything back to metadata.csv.
with open('metadata.csv', 'w', newline='') as metadata_file:
with open("metadata.csv", "w", newline="") as metadata_file:
writer = csv.DictWriter(metadata_file, metadata_fields)
writer.writeheader()
writer.writerows(metadata)
Expand All @@ -91,5 +89,39 @@ def parse_temporal_metric(line):
return {k: v.lower() for k, v in match.groupdict().items()}


if __name__ == '__main__':
def extract_metric_defs(go_code: str) -> dict:
"""
Extract metric definitions from Go code that are function calls starting with 'New' and containing 'Def'.

Args:
go_code (str): The Go source code content

Returns:
dict: Dictionary with metric name as key and type as value
"""
results = {}

# Regular expression to match variable declarations with New*Def function calls
# This pattern looks for:
# 1. Variable name
# 2. = New*Def(
# 3. Metric name in quotes
pattern = r'(\w+)\s*=\s*(New\w*Def)\s*\(\s*"([^"]+)"'

# Find all matches in the code
matches = re.finditer(pattern, go_code)

for match in matches:
func_name = match.group(2)
metric_name = match.group(3)

# Extract type from function name (everything between New and Def)
type_name = func_name[3:-3] # Remove "New" prefix and "Def" suffix

results[metric_name.lower()] = type_name.lower()

return results


if __name__ == "__main__":
main()
94 changes: 35 additions & 59 deletions temporal/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,34 +100,25 @@
"temporal.server.activity.end_to_end_latency.bucket",
"temporal.server.activity.end_to_end_latency.count",
"temporal.server.activity.end_to_end_latency.sum",
"temporal.server.activity_info.bucket",
"temporal.server.activity_info.count",
"temporal.server.activity_info.size.bucket",
"temporal.server.activity_info.size.count",
"temporal.server.activity_info.size.sum",
"temporal.server.activity_info.sum",
"temporal.server.add_search_attributes.workflow_failure",
"temporal.server.add_search_attributes.workflow_failure.count",
"temporal.server.add_search_attributes.workflow_success.count",
"temporal.server.buffered_events.bucket",
"temporal.server.buffered_events.count",
"temporal.server.buffered_events.size.bucket",
"temporal.server.buffered_events.size.count",
"temporal.server.buffered_events.size.sum",
"temporal.server.buffered_events.sum",
"temporal.server.cache.latency.bucket",
"temporal.server.cache.latency.count",
"temporal.server.cache.latency.sum",
"temporal.server.cache.miss.count",
"temporal.server.cache.requests.count",
"temporal.server.certificates.expired",
"temporal.server.certificates.expiring",
"temporal.server.child_info.bucket",
"temporal.server.child_info.count",
"temporal.server.child_info.size.bucket",
"temporal.server.child_info.size.count",
"temporal.server.child_info.size.sum",
"temporal.server.child_info.sum",
"temporal.server.client.errors.count",
"temporal.server.client.latency.bucket",
"temporal.server.client.latency.count",
Expand All @@ -138,13 +129,6 @@
"temporal.server.client.redirection.latency.sum",
"temporal.server.client.redirection.requests.count",
"temporal.server.client.requests.count",
"temporal.server.cluster_metadata.callback.lock_latency.bucket",
"temporal.server.cluster_metadata.callback.lock_latency.count",
"temporal.server.cluster_metadata.callback.lock_latency.sum",
"temporal.server.cluster_metadata.lock_latency.bucket",
"temporal.server.cluster_metadata.lock_latency.count",
"temporal.server.cluster_metadata.lock_latency.sum",
"temporal.server.complete_workflow_command.count",
"temporal.server.complete_workflow_task_sticky.enabled.count",
"temporal.server.elasticsearch.bulk_processor.bulk_size.bucket",
"temporal.server.elasticsearch.bulk_processor.bulk_size.count",
Expand Down Expand Up @@ -194,7 +178,6 @@
"temporal.server.history.sum",
"temporal.server.lease.requests.count",
"temporal.server.local_to_local.matches.count",
"temporal.server.lock.failures.count",
"temporal.server.lock.latency.bucket",
"temporal.server.lock.latency.count",
"temporal.server.lock.latency.sum",
Expand All @@ -205,15 +188,6 @@
"temporal.server.mutable_state.size.bucket",
"temporal.server.mutable_state.size.count",
"temporal.server.mutable_state.size.sum",
"temporal.server.namespace_cache.callbacks_latency.bucket",
"temporal.server.namespace_cache.callbacks_latency.count",
"temporal.server.namespace_cache.callbacks_latency.sum",
"temporal.server.namespace_cache.prepare_callbacks_latency.bucket",
"temporal.server.namespace_cache.prepare_callbacks_latency.count",
"temporal.server.namespace_cache.prepare_callbacks_latency.sum",
"temporal.server.namespace_registry.lock_latency.bucket",
"temporal.server.namespace_registry.lock_latency.count",
"temporal.server.namespace_registry.lock_latency.sum",
"temporal.server.new_timer_notifications.count",
"temporal.server.numshards",
"temporal.server.pending_tasks.bucket",
Expand Down Expand Up @@ -242,13 +216,9 @@
"temporal.server.replication.tasks.lag.bucket",
"temporal.server.replication.tasks.lag.count",
"temporal.server.replication.tasks.lag.sum",
"temporal.server.request_cancel_info.bucket",
"temporal.server.request_cancel_info.count",
"temporal.server.request_cancel_info.size.bucket",
"temporal.server.request_cancel_info.size.count",
"temporal.server.request_cancel_info.size.sum",
"temporal.server.request_cancel_info.sum",
"temporal.server.schedule_activity_command.count",
"temporal.server.search_attributes_size.bucket",
"temporal.server.search_attributes_size.count",
"temporal.server.search_attributes_size.sum",
Expand All @@ -257,7 +227,6 @@
"temporal.server.service.authorization_latency.sum",
"temporal.server.service.error_with_type.count",
"temporal.server.service.errors.count",
"temporal.server.service.errors.critical.count",
"temporal.server.service.errors.resource_exhausted.count",
"temporal.server.service.latency.bucket",
"temporal.server.service.latency.count",
Expand All @@ -270,32 +239,13 @@
"temporal.server.service.latency.userlatency.sum",
"temporal.server.service.pending_requests",
"temporal.server.service.requests.count",
"temporal.server.shard.lock_latency.bucket",
"temporal.server.shard.lock_latency.count",
"temporal.server.shard.lock_latency.sum",
"temporal.server.shard_controller.lock_latency.bucket",
"temporal.server.shard_controller.lock_latency.count",
"temporal.server.shard_controller.lock_latency.sum",
"temporal.server.shardinfo.replication.lag.bucket",
"temporal.server.shardinfo.replication.lag.count",
"temporal.server.shardinfo.timer.lag.bucket",
"temporal.server.shardinfo.timer.lag.count",
"temporal.server.shardinfo.timer.lag.sum",
"temporal.server.shardinfo.transfer.lag.bucket",
"temporal.server.shardinfo.transfer.lag.count",
"temporal.server.shardinfo.visibility.lag.bucket",
"temporal.server.shardinfo.visibility.lag.count",
"temporal.server.shardinfo.visibility.lag.sum",
"temporal.server.sharditem.acquisition_latency.bucket",
"temporal.server.sharditem.acquisition_latency.count",
"temporal.server.sharditem.acquisition_latency.sum",
"temporal.server.sharditem.created.count",
"temporal.server.signal_info.bucket",
"temporal.server.signal_info.count",
"temporal.server.signal_info.size.bucket",
"temporal.server.signal_info.size.count",
"temporal.server.signal_info.size.sum",
"temporal.server.signal_info.sum",
"temporal.server.state_transition.bucket",
"temporal.server.state_transition.count",
"temporal.server.state_transition.sum",
Expand All @@ -306,8 +256,6 @@
"temporal.server.task.attempt.count",
"temporal.server.task.attempt.sum",
"temporal.server.task.batch_complete_counter.count",
"temporal.server.task.bucket",
"temporal.server.task.count",
"temporal.server.task.lag_per_tl",
"temporal.server.task.latency.bucket",
"temporal.server.task.latency.count",
Expand All @@ -324,24 +272,17 @@
"temporal.server.task.latency.schedule.count",
"temporal.server.task.latency.schedule.sum",
"temporal.server.task.latency.sum",
"temporal.server.task.latency.user.bucket",
"temporal.server.task.latency.user.count",
"temporal.server.task.latency.user.sum",
"temporal.server.task.requests.count",
"temporal.server.task.schedule_to_start_latency.bucket",
"temporal.server.task.schedule_to_start_latency.count",
"temporal.server.task.schedule_to_start_latency.sum",
"temporal.server.task.sum",
"temporal.server.task_queue.started.count",
"temporal.server.task_rescheduler.pending_tasks.bucket",
"temporal.server.task_rescheduler.pending_tasks.count",
"temporal.server.task_rescheduler.pending_tasks.sum",
"temporal.server.timer_info.bucket",
"temporal.server.timer_info.count",
"temporal.server.timer_info.size.bucket",
"temporal.server.timer_info.size.count",
"temporal.server.timer_info.size.sum",
"temporal.server.timer_info.sum",
"temporal.server.version_check.failed.count",
"temporal.server.version_check.latency.bucket",
"temporal.server.version_check.latency.count",
Expand All @@ -360,4 +301,39 @@
"temporal.server.workflow.task.attempt.count",
"temporal.server.workflow.task.attempt.sum",
"temporal.server.workflow.task.timeout_overrides.count",
"temporal.server.gomaxprocs",
"temporal.server.memory.allocated",
"temporal.server.memory.gc_pause_ms.bucket",
"temporal.server.memory.gc_pause_ms.count",
"temporal.server.memory.gc_pause_ms.sum",
"temporal.server.memory.heap",
"temporal.server.memory.heapidle",
"temporal.server.memory.heapinuse",
"temporal.server.memory.num_gc.bucket",
"temporal.server.memory.num_gc.count",
"temporal.server.memory.num_gc.sum",
"temporal.server.memory.stack",
"temporal.server.num_goroutines",
"temporal.server.restarts.count",
"temporal.server.activity_info.count.bucket",
"temporal.server.activity_info.count.count",
"temporal.server.activity_info.count.sum",
"temporal.server.buffered_events.count.bucket",
"temporal.server.buffered_events.count.count",
"temporal.server.buffered_events.count.sum",
"temporal.server.child_info.count.bucket",
"temporal.server.child_info.count.count",
"temporal.server.child_info.count.sum",
"temporal.server.request_cancel_info.count.bucket",
"temporal.server.request_cancel_info.count.count",
"temporal.server.request_cancel_info.count.sum",
"temporal.server.signal_info.count.bucket",
"temporal.server.signal_info.count.count",
"temporal.server.signal_info.count.sum",
"temporal.server.task.count.bucket",
"temporal.server.task.count.count",
"temporal.server.task.count.sum",
"temporal.server.timer_info.count.bucket",
"temporal.server.timer_info.count.count",
"temporal.server.timer_info.count.sum",
]
3 changes: 2 additions & 1 deletion temporal/tests/compose/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ services:
elasticsearch:
condition: service_healthy
environment:
- DB=postgresql
- DB=postgres12
- DB_PORT=5432
- POSTGRES_USER=temporal
- POSTGRES_PWD=temporal
Expand All @@ -54,6 +54,7 @@ services:
- ES_SEEDS=elasticsearch
- ES_VERSION=v7
- PROMETHEUS_ENDPOINT=0.0.0.0:8000
- TEMPORAL_ADDRESS=temporal:7233
image: temporalio/auto-setup:${TEMPORAL_VERSION}
networks:
- temporal-network
Expand Down
Loading
Loading