Skip to content

What Kyvero extensions log

Every extension we sell writes down what it did, and what it refused to do and why, in one file on your own server. Your admin lists that file on a screen you already have, with a Download button beside it.

This page is what is in it, what is deliberately not in it, and how to read it.

What this is, and what it is not

This is not a record of who changed what in your admin. On the OpenCart marketplace, "log" usually means exactly that: an audit journal in a database table, telling you which user edited which product and when. That is a useful thing and it is not this thing. We do not record admin actions, settings saves, or who was signed in.

This is what the extensions wrote down about their own work. A scheduled pass finished, and what it did. An install was refused, and the reason. A feed could not be written, and what threw. It answers "what did the extension do, and why did it not do what I expected", which is the question a support exchange starts with.

It is one file for the whole catalogue, not one per extension, because the interesting failures span extensions and because one file is one click.

Where it is, and getting it

Go to System → Maintenance → Error Logs and pick the kyvero.log tab. OpenCart lists every log file in the store's log directory as its own tab, so your Kyvero log sits beside the store's own error log with the same Download button on it.

Download it and attach it. That is the whole of getting it to us. See support for what else to include.

How to read it

Every line has the same six fields, always present and always in the same places, then the message:

2026-09-09 14:03:21 - kyvero back_in_stock/1.4.2 ERROR cron store:0 | swept: 12 sent, 1 failed, 3 not sendable

The date and time, the kyvero marker, the extension and the version of it that wrote the line, the level, where it was running, which store it was about, then a pipe and the message.

Open it in a text editor rather than reading it in the browser tab. A line runs 66 to 72 characters of structure before the message begins, so the file wants a window about 160 columns wide. Wrapped at 80, every line reads as two and the columns stop lining up, which is the thing that makes the file scannable at all.

Search the level first. ERROR and WARN are the lines where something went wrong or was refused; the rest is ordinary work being reported. On a test file of 148 lines, seven matched ERROR or WARN, and those seven were the only ones worth reading.

Do not start by searching the extension's name. It is the obvious move and it is the wrong one: the same file returned 62 lines for the extension's code, of which 53 were the same routine entry repeated. The name narrows the file to one extension and tells you nothing about which lines matter. Find the level first, then read what is around it: the lines either side of a fault are usually the context for it.

A file that starts mid-story has been trimmed, not broken. It is capped at 1 MiB (a month or two of history on a typical store), and when it reaches that it drops its oldest half and writes one line at the top saying it did. There is no second, older file: what the tab shows you is all there is.

What is in it

Three kinds of line, and every extension writes all three:

  • Something went wrong, or was refused. Thrown or deliberate, both. An install that refused itself because a permission was missing or the OpenCart release was below the extension's floor writes a line saying so. That is the case where the store would otherwise show you a blank page and nothing else.
  • The extension's own state on this store changed: it was installed, or uninstalled. An update is an uninstall and an install next to each other, and the version on every line is what makes that legible.
  • A pass finished: anything a schedule or a person started, including the passes that did nothing and the ones that stopped before they started, because the module is switched off or because the schedule you chose has not come round. Nothing needed doing and the schedule never ran look identical from the outside, and this line is what tells them apart, so it is written whether or not detailed logging is on.

There is no per-extension list on this page, and the shortness is the point: one page describes what every extension we ship writes, because they all write the same three things in the same shape.

What is deliberately not in it

One rule decides every case: a line may carry an identifier, never an attribute. An order id, a customer id, a product id: yes. A name, an email address, a postal address, a phone number, an order total, a return reason, or anything a shopper typed: no. Only you can resolve an id to a person, and that is the feature: we diagnose the mechanism, you resolve the identity.

Server details are out on the same rule: no absolute filesystem paths, no tokens, no keys, no credentials, no connection details.

What we can promise is what we do, and it stops short of a promise about the file's contents. Three different things hold that rule up, and they are worth telling apart, because a check that is claimed to do more than it does retires the review that was actually doing the work:

  • Decided by the build, on every release. Two shapes are refused outright: a log line whose argument is a filesystem path construct, and one naming any of five personal fields: email, firstname, lastname, telephone, postcode. Both are decidable from the source of the call itself, which is exactly why these two and no others. Separately, every message that reaches the file has any email address stripped out of it on the way, which is the one backstop that runs at the moment of writing. An email address is the one prohibited value with a shape a machine can recognise.
  • Decided by installing on a real store. The build reads source, so it can only judge what a line is written as. What a line says at runtime needs a store, and that is a separate pass: we install every extension on a throwaway store, read the file it wrote, and fail the release if it names an absolute path of the machine it ran on. That check is not a duplicate of the one above, and it has already earned its place: one extension shipped a server path into a line by storing it on a record and then logging the record, where no source check was ever going to see it.
  • Trusted, and read by people. Everything else, and it is not a short list. The rule above is a sentence a person follows: free prose, an order total, a return reason, a user agent are prohibited by it and checked by nothing. An IP address is trusted rather than checked. We measured a check for it and refused to ship one, because the word matches 142 unrelated names across the catalogue and a rule that fires mostly on false matches is a rule people learn to wave through. Also trusted: which level a line is written at, whether detailed logging adds a line per pass or a line per record, and whether a message is any good to the person reading it.

So: we do not tell you this file is free of personal data. What we tell you is what the extensions are written and checked to do: name records by their id, and strip an email address out of any message on the way to the file. In practice that means there is nothing to remove before you send it to us, and it is why support asks you to attach it rather than warning you off it. It is not a guarantee about every byte, and we are not going to write one.

Detailed logging

Every extension's settings screen has a Detailed logging switch, under Diagnostics. It is the answer to "can you reproduce it with more detail": turn it on for the one extension that is misbehaving, do the thing again, then send the file.

Three things about it:

  • It records what the extension did in far more detail: the settings that governed a pass, each decision and the branch it took, the counts behind a zero. Detail per pass and per decision, and deliberately not a line per record: one line per product on a run of eight thousand would spend the file in a single pass and take the history you turned it on to look at with it.
  • It turns itself off two days after you turn it on, and the switch shows you the date and time it expires rather than a checked box. Forgetting it is not a state you can get into.
  • While it is on, the file holds less history. The extra detail goes into the same file, and the file is a fixed size, so the further back you can read gets shorter. That is the trade, and it is the reason the switch expires on its own.

It is one switch for the whole installation, set on the default store's form. Any other store shows you the state and a link to where the switch is.

Where the file lives on disk

It is kyvero.log, in your store's own log directory, system/storage/logs/ on a stock install, which is inside your web root. That is OpenCart's default location for its own logs, and it is exactly as true of the error log your store has been writing since the day it was installed.

What that means on a public store: somebody who knows or guesses the path could fetch the file over HTTP, exactly as they could fetch error.log. We add no protection of our own, deliberately. An .htaccess dropped into a core directory by an extension works on Apache alone, is silently ignored everywhere else, and would still be sitting there after the extension is uninstalled. A false reassurance is worse than the plain fact.

The two answers that do work apply to the whole directory rather than to one file in it. Your host can deny web access to it at the server, and OpenCart's storage directory is a line in your store's config.php which can point somewhere outside the web root entirely, and every log your store writes, ours included, moves with it. Neither is something an extension can do for you.

It is also the second reason the rule above is what it is: the file is written as though somebody might read it, because on a stock store somebody might.

Nothing leaves your server

The file is written on your server, read from your admin, and sent to nobody. There is no telemetry, no crash reporting, no call home, and no setting that turns any of that on. The extensions have nowhere to send it. It reaches us when you download it and attach it to a support request, and that is the only route there is.

One caveat, and it is the same one the API promise makes about its own messages: these lines are prose, written for a person to read. The shape will change when we find a better one. Never build anything that parses them.