Skip to content

Commit 4802d2f

Browse files
authored
Log forwarding support (#413)
Fixes #311
1 parent 6dbe2f4 commit 4802d2f

File tree

8 files changed

+461
-71
lines changed

8 files changed

+461
-71
lines changed

temporalio/bridge/Cargo.lock

Lines changed: 26 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

temporalio/bridge/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ name = "temporal_sdk_bridge"
88
crate-type = ["cdylib"]
99

1010
[dependencies]
11+
futures = "0.3"
1112
log = "0.4"
1213
once_cell = "1.16.0"
1314
parking_lot = "0.12"
1415
prost = "0.11"
1516
prost-types = "0.11"
16-
pyo3 = { version = "0.18", features = ["extension-module", "abi3-py37"] }
17-
pyo3-asyncio = { version = "0.18", features = ["tokio-runtime"] }
17+
pyo3 = { version = "0.19", features = ["extension-module", "abi3-py37"] }
18+
pyo3-asyncio = { version = "0.19", features = ["tokio-runtime"] }
19+
pythonize = "0.19"
1820
temporal-client = { version = "0.1.0", path = "./sdk-core/client" }
1921
temporal-sdk-core = { version = "0.1.0", path = "./sdk-core/core", features = ["ephemeral-server"] }
2022
temporal-sdk-core-api = { version = "0.1.0", path = "./sdk-core/core-api" }

temporalio/bridge/runtime.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
from __future__ import annotations
77

88
from dataclasses import dataclass
9-
from typing import Any, Mapping, Optional, Sequence, Type
9+
from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Type
10+
11+
from typing_extensions import Protocol
1012

1113
import temporalio.bridge.temporal_sdk_bridge
1214

@@ -29,13 +31,21 @@ def retrieve_buffered_metrics(self) -> Sequence[Any]:
2931
"""Get buffered metrics."""
3032
return self._ref.retrieve_buffered_metrics()
3133

34+
def write_test_info_log(self, message: str, extra_data: str) -> None:
35+
"""Write a test core log at INFO level."""
36+
self._ref.write_test_info_log(message, extra_data)
37+
38+
def write_test_debug_log(self, message: str, extra_data: str) -> None:
39+
"""Write a test core log at DEBUG level."""
40+
self._ref.write_test_debug_log(message, extra_data)
41+
3242

3343
@dataclass(frozen=True)
3444
class LoggingConfig:
3545
"""Python representation of the Rust struct for logging config."""
3646

3747
filter: str
38-
forward: bool
48+
forward_to: Optional[Callable[[Sequence[BufferedLogEntry]], None]]
3949

4050

4151
@dataclass(frozen=True)
@@ -75,3 +85,42 @@ class TelemetryConfig:
7585

7686
logging: Optional[LoggingConfig]
7787
metrics: Optional[MetricsConfig]
88+
89+
90+
# WARNING: This must match Rust runtime::BufferedLogEntry
91+
class BufferedLogEntry(Protocol):
92+
"""A buffered log entry."""
93+
94+
@property
95+
def target(self) -> str:
96+
"""Target category for the log entry."""
97+
...
98+
99+
@property
100+
def message(self) -> str:
101+
"""Log message."""
102+
...
103+
104+
@property
105+
def time(self) -> float:
106+
"""Time as from ``time.time`` since Unix epoch."""
107+
...
108+
109+
@property
110+
def level(self) -> int:
111+
"""Python log level, with trace as 9."""
112+
...
113+
114+
@property
115+
def fields(self) -> Dict[str, Any]:
116+
"""Additional log entry fields.
117+
Requesting this property performs a conversion from the internal
118+
representation to the Python representation on every request. Therefore
119+
callers should store the result instead of repeatedly calling.
120+
121+
Raises:
122+
Exception: If the internal representation cannot be converted. This
123+
should not happen and if it does it is considered a bug in the
124+
SDK and should be reported.
125+
"""
126+
...

temporalio/bridge/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ fn temporal_sdk_bridge(py: Python, m: &PyModule) -> PyResult<()> {
2626

2727
// Runtime stuff
2828
m.add_class::<runtime::RuntimeRef>()?;
29+
m.add_class::<runtime::BufferedLogEntry>()?;
2930
m.add_function(wrap_pyfunction!(init_runtime, m)?)?;
3031
m.add_function(wrap_pyfunction!(raise_in_thread, m)?)?;
3132

0 commit comments

Comments
 (0)