> ## Documentation Index
> Fetch the complete documentation index at: https://imsdkdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging and Diagnostics

> Simplified and raw GStreamer logging in the QIM SDK Python Pipeline SDK

A GStreamer pipeline is verbose by nature: with `GST_DEBUG` turned up, every element reports on every buffer, and the output quickly reaches thousands of lines per second. That is the right tool when debugging an element's internals, and the wrong one when the question is simply *did my pipeline link the way I intended*.

The SDK therefore offers two ways to look at the same pipeline:

* **Simplified logs** — the SDK reads GStreamer's log stream, keeps only what is meaningful at application level (state changes, errors, performance figures), and reprints it in a compact, uniform format alongside its own diagnostics. This is the default.
* **Raw GStreamer logs** — the SDK steps out of the way and lets GStreamer log exactly as it normally would, with `GST_DEBUG` fully in control.

Which one is active is decided by `SetImsdkGstLogMode()`; how much detail the SDK's own diagnostics carry is decided independently by `SetImsdkLogLevel()`.

## Responsibilities

* Route GStreamer's log stream either through the SDK's parser or through GStreamer's default handler.
* Filter the SDK's own diagnostics by verbosity level.
* Recognize state changes, errors, and performance reports in GStreamer's output and re-emit them in a uniform format.
* Clean up the parser and its temporary log file when the runtime shuts down.

## APIs

Everything below is exported from the `qimsdk` package.

| `qimsdk`                                            | Description                                                                                                                                     |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `SetImsdkLogLevel(level: ImsdkLogLevel) -> None`    | Sets the verbosity of the SDK's own diagnostics. Records below the selected level are suppressed. Effective at any time.                        |
| `SetImsdkGstLogMode(mode: ImsdkGstLogMode) -> None` | Selects simplified or raw GStreamer logging. Must be called before the first `Pipeline` is constructed — see the warning under [Usage](#usage). |

| `ImsdkLogLevel` | Prints                                                                                                                                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Error`         | Failures only — including the caps of any pads left unlinked when a link or a state change fails.                                                                                                      |
| `Warning`       | The above, plus recoverable problems.                                                                                                                                                                  |
| `Info`          | The above, plus lifecycle milestones and pipeline state changes. **Default.**                                                                                                                          |
| `Debug`         | Everything, plus the resolved topology — each element with its pad-to-pad connections and any still-pending deferred links — and the per-element performance figures reported by the Qualcomm plugins. |

Both are `IntEnum` types, so `ImsdkLogLevel.Debug` and the plain integer `3` are interchangeable.

## Simplified logs — `ImsdkGstLogMode.ImsdkLog`

The default. The SDK lowers GStreamer's global threshold to errors only, then re-enables the `LOG` level for a specific set of categories it knows how to interpret — `GST_STATE`, `GST_STATES`, and the Qualcomm element categories (`qtimlvconverter`, `qtimlpostprocess`, `qtimltflite`, `qtivcomposer`, `qtivoverlay`, and the rest). Everything else GStreamer would have printed is dropped.

Of what remains, it recognizes three things and reformats them: **completed state changes**, **errors**, and **performance/HW-utilization reports** from the plugins. Each is re-emitted through the SDK's logger, in the same format as the SDK's own diagnostics.

The result is one uniform stream:

```
[QIM SDK][INFO][STATE][cam-pipeline] PLAYING
[QIM SDK][DEBUG][qtimltflite0] Performance time 12.4 ms, HW utilization: 38%
[QIM SDK][ERROR][qtimlpostprocess] postprocessing <error text from GStreamer>
```

Errors carry the GStreamer category and the offending object's name before the message itself. Only the level token is colorized — red for `ERROR`, yellow for `WARN`, green for `INFO` — which is convenient interactively and unhelpful in a log file. Set `IMSDK_LOG_COLOR` to `0`, `false`, or `off` to disable the escape codes.

<Note>
  This mode routes GStreamer's output through `~/gst.log` and tails that file from a background thread, rather than attaching a log callback in-process. Two consequences follow: `GST_DEBUG_FILE` is set by the SDK and any value you set for it yourself is overwritten, and the file is created on startup and removed on shutdown. Parsed lines are emitted asynchronously, so they can appear slightly out of order relative to your own `print()` output.
</Note>

<Note>
  Because this mode reconfigures GStreamer's thresholds, a `GST_DEBUG` value set in the environment does not have its usual effect: categories the SDK does not interpret are silenced regardless. If you set `GST_DEBUG` and see less than you expected, this is why — use raw mode instead.
</Note>

### Integration with Python's `logging`

The SDK emits through a standard `logging.Logger` named `imsdk`, so it composes with the rest of a Python application's logging setup. `SetImsdkLogLevel()` maps onto the usual Python levels (`Error` → `ERROR`, `Warning` → `WARNING`, `Info` → `INFO`, `Debug` → `DEBUG`) and sets the level on that logger.

By default the SDK installs its own `StreamHandler` with the `[IMSDK][LEVEL]` formatter and sets `propagate = False`, so its records do not reach the root logger and will not be duplicated by an application-level `basicConfig()`. To route them into your own handlers instead, attach to the `imsdk` logger directly:

```python theme={null}
import logging

imsdk_log = logging.getLogger("imsdk")
imsdk_log.addHandler(my_handler)
```

## Raw GStreamer logs — `ImsdkGstLogMode.GstLog`

In this mode the SDK installs no parser at all — no log file, no background reader thread — and leaves GStreamer's own handler in place. GStreamer's log configuration is left untouched apart from the default threshold, which is aligned with the level passed to `SetImsdkLogLevel()`, so `GST_DEBUG` behaves as it does in any other GStreamer application.

```bash theme={null}
GST_DEBUG=3 python3 my_app.py                    # all categories, warnings and up
GST_DEBUG=qtimlvconverter:5 python3 my_app.py    # one element, in full detail
```

Output goes to standard error in GStreamer's familiar format — timestamp, PID, thread, level, category, file, line, object — and honours the usual GStreamer environment variables.

Use raw mode when the problem is inside an element rather than in the graph: caps negotiation that fails for a non-obvious reason, an element misbehaving mid-stream, or anything where a GStreamer maintainer would ask for a full log. The SDK's own diagnostics continue to be emitted as usual and remain governed by `SetImsdkLogLevel()`.

## Choosing between them

|              | Simplified (`ImsdkLog`)                                 | Raw (`GstLog`)                               |
| ------------ | ------------------------------------------------------- | -------------------------------------------- |
| Volume       | A handful of lines per pipeline                         | Thousands of lines per second at high levels |
| Format       | `[IMSDK][LEVEL]`, uniform with SDK diagnostics          | GStreamer's native format                    |
| Stream       | The `imsdk` Python logger                               | Standard error                               |
| `GST_DEBUG`  | Overridden — only interpreted categories survive        | Fully honoured                               |
| Side effects | Uses `~/gst.log` and a reader thread                    | None                                         |
| Best for     | Did the graph build correctly? Is it running? How fast? | Why is this element failing internally?      |

## Usage

Set the mode before the first `Pipeline` is created, and the level wherever it is convenient:

```python theme={null}
from qimsdk import (
    Pipeline,
    VideoFilter,
    ImsdkGstLogMode,
    ImsdkLogLevel,
    SetImsdkGstLogMode,
    SetImsdkLogLevel,
)

SetImsdkGstLogMode(ImsdkGstLogMode.ImsdkLog)
SetImsdkLogLevel(ImsdkLogLevel.Debug)

pipeline = (
    Pipeline("my-pipeline")
    .add("qtiqmmfsrc", "source")
    .add_stream_filter("vf", VideoFilter().format("NV12"))
    .add("waylandsink", "display", "fullscreen", True)
)

pipeline.execute()
```

<Warning>
  The log mode is read once, when the SDK's runtime starts — which happens implicitly on the first `Pipeline` that gets constructed. A `SetImsdkGstLogMode()` call after that point is silently ignored. Put it before any pipeline is built. `SetImsdkLogLevel()` has no such restriction and can be changed at any time.
</Warning>

<Tip>
  When a pipeline fails to start or a link does not resolve, the caps of the unlinked pads are reported at `Error` level, so they appear without any configuration. Raise the level to `Debug` to also see the topology the pipeline actually built — the quickest way to confirm that a deferred link resolved to the pad you expected. Reach for raw mode only once the graph itself is known to be correct.
</Tip>

## Related

* [SDK Architecture and API Reference](/app-builder/python-architecture-api-reference) — the `Pipeline`, `Element`, and filter APIs whose behaviour these logs describe.
* [Quick start guide](/app-builder/python-quickstart) — installation and a first pipeline.
