---
title: "Logging — SpiffWorkflow 3.0.0 documentation"
description: "the spiff.workflow logger, which emits messages when actions are taken on a workflow"
source_url: https://spiff.works/docs/spiffworkflow/bpmn/logging.html
---

☰ Menu

# Logging[](#logging "Link to this heading")

Spiff provides several loggers:

> - the `spiff.workflow` logger, which emits messages when actions are taken on a workflow
> - the `spiff.task` logger, which emits messages when tasks change state

Records emitted at the `INFO` level, with addtional attributes available for debugging if the level is lower.

Log entries emitted by the `spiff.workflow` logger contain the following extra atributes:

- `workflow_spec`: the name of the spec for this workflow
- `completed`: whether the workflow has completed
- `success`: the value of the `success` attribute

If the log level is less than 20, records include the following extra attribute:

- `tasks`: a list of the task ids in the workflow

Log entries emitted by the `spiff.task` logger contain the following extra attributes:

- `workflow_spec`: the name of the spec for this workflow
- `task_spec`: the name of the spec for this task
- `task_id`: the ID of the task)
- `task_type`: the name of the task’s spec’s class
- `state`: the name of the tasks `TaskState`
- `last_state_chsnge`: the timestamp at which the state change was made
- `elapsed`: the elapsed time since the previous state transition
- `parent`: the id of the task’s parent

If the log level is less than 20, records include the following extra attributes:

- `data` the task data
- `internal_data`: the task internal data

Log entries containing task data and internal data can be quite large, so use with caution!

In our command line UI ([cli/subcommands.py](https://github.com/sartography/spiff-example-cli/tree/main/spiff_example/cli/subcommands.py)), we’ve added a few of these extra attributes to the log records:

```
task_logger = logging.getLogger('spiff.task')
task_handler = logging.StreamHandler()
task_handler.setFormatter(logging.Formatter('%(asctime)s [%(name)s:%(levelname)s] (%(workflow_spec)s:%(task_spec)s) %(message)s'))
task_logger.addHandler(task_handler)

wf_logger = logging.getLogger('spiff.workflow')
wf_handler = logging.StreamHandler()
wf_handler.setFormatter(logging.Formatter('%(asctime)s [%(name)s:%(levelname)s] (%(workflow_spec)s) %(message)s'))
wf_logger.addHandler(wf_handler)
```
