> For the complete documentation index, see [llms.txt](https://docs.viesus.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.viesus.com/operations/monitoring.md).

# Monitoring

Production observability for VIESUS. This page covers the signals each deployment exposes — per-image result files, structured logs, GPU metrics, and Cloud API events — and the thresholds worth alerting on.

***

## On-premise monitoring

### Result files

When `WriteResultFiles: 1` is set in `viesusini.json`, VIESUS writes a `.json` or `.res` file alongside each output image. These files contain per-image processing details and are the primary observability signal for on-premise deployments.

**Node.js / CLI result JSON:**

```json
{
  "brightCorrStrength": 0.011,
  "colorCorrStrength": 0.083,
  "fdApplied": 1,
  "ieApplied": 1,
  "isArtificial": 0,
  "isMonochrome": 0,
  "rszApplied": 0,
  "arApplied": 1
}
```

All fields are `0` or a float strength value. A result file present means the image processed. A missing result file (when `WriteResultFiles: 1`) means the enhancement failed.

**PDF Enhancer XML report:**

```xml
<viesus>
  <error code="0" msg="no Failure"/>
  <processedImages total="47" enhanced="44" skipped="3"/>
  <duration ms="12430"/>
  ...
</viesus>
```

Error code `0` = success. Non-zero = partial or complete failure. See [PDF Error Codes](/support/error-codes/pdf.md).

***

### Parsing result files

**Check for CLI/Node.js errors (bash):**

```bash
#!/bin/bash
# Scan output folder for failed enhancements (missing result files)

IN_DIR="$1"
OUT_DIR="$2"
RES_DIR="$3"
ERRORS=0

while IFS= read -r img; do
    base=$(basename "${img%.*}")
    if [[ ! -f "${RES_DIR}/${base}.json" ]]; then
        echo "MISSING result: $img"
        ((ERRORS++)) || true
    fi
done < <(find "$IN_DIR" -type f -name "*.jpg")

echo "Errors: $ERRORS"
```

**Parse PDF XML reports:**

```bash
for xml in /print-queue/ready/*.xml; do
    code=$(xmllint --xpath 'string(//error/@code)' "$xml" 2>/dev/null)
    pdf=$(basename "${xml%.xml}")
    if [[ "$code" != "0" ]]; then
        echo "PDF ERROR: $pdf code=$code"
    fi
done
```

***

### Node.js module logging

Log both enhancement time and wall-clock time per job to detect pool saturation:

```js
parentPort.on('message', (job) => {
  const start = Date.now();
  const result = viesusObj.Enhance(job.fromPath, job.toPath, job.iniPath, job.resPath);
  const wall = Date.now() - start;
  parentPort.postMessage({ result, wall });
});
```

In the main thread:

```js
const { result, wall } = await pool.exec(job);
console.log(JSON.stringify({
  ts: new Date().toISOString(),
  status: result > 0 ? 'ok' : 'error',
  enhanceMs: result > 0 ? result : null,
  errorCode: result < 0 ? result : null,
  wallMs: wall,
  file: path.basename(job.fromPath),
}));
```

Structured JSON logs integrate cleanly with log aggregators (Datadog, Loki, CloudWatch).

**Key metrics to track:**

| Metric               | Alert threshold                                     |
| -------------------- | --------------------------------------------------- |
| `enhanceMs` p95      | 2× baseline — indicates degraded performance        |
| `wallMs - enhanceMs` | > 5 sec — pool is saturated (jobs queuing)          |
| Error rate           | > 1% — investigate error codes                      |
| Queue depth          | Monitor `pool.queueSize` if exposed by pool library |

***

### GPU monitoring

Check GPU utilization and VRAM usage alongside VIESUS metrics:

```bash
# One-line GPU status
nvidia-smi --query-gpu=name,utilization.gpu,memory.used,memory.total,temperature.gpu \
           --format=csv,noheader,nounits

# Continuous monitoring (every 2 seconds)
nvidia-smi dmon -s u,m -d 2

# NVML-based detailed stats (Python)
# pip install nvidia-ml-py
```

**Expected values during active GPU processing:**

| Metric          | Expected range                    |
| --------------- | --------------------------------- |
| GPU utilization | 80–100%                           |
| VRAM used       | 4–8 GB per active worker          |
| Temperature     | < 85°C (thermal throttling above) |

***

### License expiry monitoring

When a license expires, VIESUS stops enhancing — images pass through unchanged (output = input). Check license validity directly with the CLI's `-I` flag rather than inferring it from output:

```bash
#!/bin/bash
# check-license.sh — verify the VIESUS license is valid; run daily via cron

GUID="$1"

# -I prints license information (validity and, where applicable, expiry).
# For GUID libraries the GUID must be supplied with -g.
if ! info=$(viesus -I -g "$GUID"); then
    echo "ALERT: 'viesus -I' failed (exit $?) — license may be invalid or expired"
    exit 1
fi

echo "$info"
# Review the validity / expiry fields and alert when the license is invalid
# or close to expiry.
```

Run this check daily via cron and alert on a non-zero exit code.

***

## Cloud API monitoring

### Credit balance

Poll credit balance to detect approaching depletion:

```js
async function checkCredits(client) {
  const { credits } = await client.request(gql`
    query {
      credits {
        remainingCreditsThisPeriod
        usedCreditsThisPeriod
        periodEnd
      }
    }
  `);

  const remaining = credits.remainingCreditsThisPeriod;
  const periodEnd = new Date(credits.periodEnd);
  const daysLeft = Math.ceil((periodEnd - Date.now()) / 86400000);

  console.log(`Credits: ${remaining} remaining, ${daysLeft} days until period end`);

  if (remaining < 500) {
    // Alert: less than 500 credits remaining
    await sendAlert(`Low credits: ${remaining} remaining until ${credits.periodEnd}`);
  }
}
```

### Enhancement failure rate

Track error rates from webhook events:

```js
// In your webhook handler
const metrics = { finished: 0, errored: 0 };

if (status === 'FINISHED') metrics.finished++;
if (status === 'ERROR') {
  metrics.errored++;
  console.error(JSON.stringify({ event: 'enhancement_error', errorCode, uploadId }));
}

// Log hourly
setInterval(() => {
  const errorRate = metrics.errored / (metrics.finished + metrics.errored) * 100;
  console.log(`Enhancement error rate: ${errorRate.toFixed(2)}%`);
  metrics.finished = 0;
  metrics.errored = 0;
}, 3600000);
```

### Webhook delivery failures

Query webhook logs regularly to catch failed deliveries:

```graphql
query {
  webhookLogs(
    webhookId: "your-webhook-id"
    filter: { take: 50, skip: 0, status: FAILED }
  ) {
    items {
      id
      responseStatusCode
      createdAt
    }
  }
}
```

***

## Alerting recommendations

| Alert                     | Condition                                     | Priority |
| ------------------------- | --------------------------------------------- | -------- |
| Enhancement error rate    | > 2% over 15 min                              | High     |
| Pool saturation           | `wallMs - enhanceMs` > 10 sec p95             | High     |
| License invalid / expired | `viesus -I` exits non-zero or reports invalid | Critical |
| Low credits               | < 500 remaining                               | High     |
| GPU temperature           | > 85°C                                        | High     |
| Webhook failures          | > 5 consecutive failed deliveries             | Medium   |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.viesus.com/operations/monitoring.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
