Skip to content

Logging

Emit structured task logs and tune how workflow clients export log records.

Tilebox collects workflow logs automatically. When a runner is created from a Client, logs emitted through the task execution context are exported to Tilebox and correlated with the active job, task, and trace.

Job Logs View

Use context.logger inside Task.execute. It supports standard log levels and structured attributes.

from tilebox.workflows import ExecutionContext, Task
class ProcessScene(Task):
scene_id: str
def execute(self, context: ExecutionContext) -> None:
context.logger.info("Started scene processing", scene_id=self.scene_id)
log = context.logger.bind(component="atmospheric-correction")
log.debug("Fetching auxiliary data")
try:
# process the scene
log.info("Scene processed", output_format="cog")
except Exception:
context.logger.exception("Scene processing failed", scene_id=self.scene_id)
raise

Structured attributes become searchable log attributes. Bind shared attributes to a logger when records need the same context.

Logs emitted from a task include workflow metadata without extra code. Tilebox attaches job ID, job name, task ID, task display name, parent task data, task identifier name and version, runner service data, SDK version, host, OS, and process ID. When a log is emitted inside an active span, Tilebox also attaches trace_id and span_id.

Logs are also added as events on the active trace span, so a trace view can show important log messages inline with task execution.

Built-in Tilebox export does not require configuration. For local development, add a console handler to print Tilebox workflow logs to standard output.

import logging
from tilebox.workflows import Client
from tilebox.workflows.observability.logging import configure_console_logging
from my_workflow import ProcessScene
configure_console_logging(level=logging.DEBUG)
client = Client()
runner = client.runner(tasks=[ProcessScene])
runner.run_forever()

configure_console_logging() and workflows.ConfigureConsoleLogging() are process-wide for Tilebox workflow loggers. Use them for local runs and debugging distributed runners.

Use Client.configure_logging() to choose which task and runner logs a client exports to Tilebox.

import logging
from tilebox.workflows import Client
client = Client(name="sentinel-2-runner")
# Export task logs at DEBUG and internal runner logs at INFO.
client.configure_logging(level=logging.DEBUG, runner_level=logging.INFO)

The Python level argument applies to logs emitted with context.logger. The optional runner_level argument applies to internal runner logs. If runner_level is omitted, it uses the same value as level. In Go, workflows.ConfigureConsoleLogging() sets the local console log level, and workflows.NewClient() configures Tilebox workflow log export.

You can retrieve logs for a job through the jobs client. Python results can also be converted to a pandas DataFrame.

from tilebox.workflows import Client
client = Client()
job = client.jobs().submit("process-scene", ProcessScene(scene_id="S2A_001"))
logs = client.jobs().query_logs(job)
for record in logs:
print(record.time, record.severity_text, record.body, record.attributes)
df = logs.to_pandas()

See Query telemetry for the log and span query APIs.

Tilebox stores logs by default. To export logs to your own observability backend as well, configure an OpenTelemetry or Axiom integration when the runner process starts.