Skip to content

Commit 6b00eab

Browse files
smflorentinoclaude
andcommitted
feat: add UIPATH_LOG_TO_FILE env var for file logging without job context
Adds a `log_to_file` flag that enables file-based logging (`__uipath/execution.log`) without requiring `UIPATH_JOB_KEY` to be set. This allows developers to reproduce and debug file-logging issues locally without triggering job-related side effects (licensing headers, output.json writes, state file preservation). Set `UIPATH_LOG_TO_FILE=true` to enable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0d3231a commit 6b00eab

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

src/uipath/runtime/context.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class UiPathRuntimeContext(BaseModel):
3232
resume: bool = False
3333
command: str | None = None
3434
job_id: str | None = None
35+
log_to_file: bool = False
3536
conversation_id: str | None = Field(
3637
None, description="Conversation identifier for CAS"
3738
)
@@ -188,6 +189,7 @@ def __enter__(self):
188189
dir=self.runtime_dir,
189190
file=self.logs_file,
190191
job_id=self.job_id,
192+
log_to_file=self.log_to_file,
191193
)
192194
self.logs_interceptor.setup()
193195

@@ -327,6 +329,9 @@ def with_defaults(
327329

328330
# Apply defaults from env
329331
base.job_id = os.environ.get("UIPATH_JOB_KEY")
332+
base.log_to_file = (
333+
os.environ.get("UIPATH_LOG_TO_FILE", "").lower() == "true"
334+
)
330335
base.logs_min_level = os.environ.get("LOG_LEVEL", "INFO")
331336
base.org_id = os.environ.get("UIPATH_ORGANIZATION_ID")
332337
base.tenant_id = os.environ.get("UIPATH_TENANT_ID")

src/uipath/runtime/logging/_interceptor.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def __init__(
2828
job_id: str | None = None,
2929
execution_id: str | None = None,
3030
log_handler: logging.Handler | None = None,
31+
log_to_file: bool = False,
3132
):
3233
"""Initialize the log interceptor.
3334
@@ -38,6 +39,7 @@ def __init__(
3839
job_id (str, optional): If provided, logs go to file; otherwise, to stdout.
3940
execution_id (str, optional): Unique identifier for this execution context.
4041
log_handler (logging.Handler, optional): Custom log handler to use for this execution context.
42+
log_to_file (bool): If True, force file logging even without a job_id.
4143
"""
4244
min_level = min_level or "INFO"
4345
self.job_id = job_id
@@ -67,8 +69,8 @@ def __init__(
6769
if log_handler:
6870
self.log_handler = log_handler
6971
else:
70-
# Create either file handler (runtime) or stdout handler (debug)
71-
if not job_id:
72+
# Create either file handler (runtime/log_to_file) or stdout handler (debug)
73+
if not job_id and not log_to_file:
7274
# Only wrap if stdout is using a problematic encoding (like cp1252 on Windows)
7375
if (
7476
hasattr(sys.stdout, "encoding")

0 commit comments

Comments
 (0)