Services
Cache, logs and debugging
Cache
CacheManager returns a cache engine per usage domain. Each domain can use its own engine, path and time to live.
Koshkil::Uses('sys.cache.CacheManager');
$cache = CacheManager::engine('query'); // or 'default', 'models', 'i18n', 'plugins'…
$key = 'productos:destacados';
$list = $cache->get($key);
if ($list === null) {
$list = TMProductos::where('prd_destacado', '1')->getAsArray();
$cache->set($key, $list, 300); // 5 minutes
}
Methods available in every engine (CacheInterface):
| Method | Purpose |
|---|---|
get($key, $default = null) |
Reads a value. |
set($key, $value, $ttl = 0) |
Stores it (0 = the domain's TTL). |
has($key), delete($key) |
|
getMultiple(), setMultiple(), deleteMultiple() |
Group operations. |
increment($key), decrement($key) |
Counters. |
clear() / flush() |
Empties the domain / the engine. |
getStats() |
Statistics. |
Configuration
// config/cache.php (summary)
$CONFIG = [
'Cache' => [
'enabled' => true,
'default' => 'file', // 'file', 'redis' or 'null'
'globalTTL' => 3600,
'engines' => [
'file' => ['path' => Koshkil::getPath('/tmp/cache', true), 'format' => 'json', 'subdirectories' => 2],
'redis' => ['enabled' => false, 'host' => '127.0.0.1', 'port' => 6379, 'prefix' => 'koshkil_'],
'null' => ['enabled' => true],
],
'domains' => [
'i18n' => ['engine' => 'file', 'ttl' => 3600],
'models' => ['engine' => 'default', 'ttl' => 86400],
'plugins' => ['engine' => 'default', 'ttl' => 3600],
'query' => ['engine' => 'default', 'ttl' => 300, 'enabled' => false],
'session' => ['engine' => 'default', 'ttl' => 7200],
],
],
];
| Domain | What the framework stores |
|---|---|
models |
Each table's structure, invalidated when the model file changes. |
i18n |
Parsed translation JSON files. |
plugins |
Each plugin's configuration and permissions. |
query |
Free for your own queries (disabled by default). |
The null engine stores nothing: use it for tests or to disable a domain. Redis requires PHP's redis extension.
Clearing and warming
- In the admin panel, Sistema → Caché shows per-domain statistics and lets you clear or warm the caches.
- From the terminal, after deploying:
./app/bin/warm-cache.sh # translations, models and plugins
php app/bin/warm-cache.php --domain=i18n --verbose
php app/bin/warm-cache.php --force # clear before warming
?reset_pluginson any URL re-reads the plugin configuration.- Files in
tmp/cache/can be deleted safely: they are rebuilt automatically.
Logs
KoshkilLog writes to tmp/logs/<name>.log. With Debug.Level at 0 nothing is written.
KoshkilLog::error('Payment failed', ['order' => 123]); // error.log
KoshkilLog::warning('Low stock', $producto->record()); // warning.log
KoshkilLog::info('Order confirmed'); // info.log
KoshkilLog::debug('Supplier response', $json); // debug.log
KoshkilLog::addLog('payments', 'Webhook received', $_POST); // payments.log
Debug.Level |
Effect |
|---|---|
| 0 | No logs. |
| 1 | Logs; attached data has passwords and full card numbers masked. |
| 2 | Logs; passwords and card numbers are masked. |
| 3 | Logs; card numbers are masked. |
| 6 or more | Also logs every SQL query to debug.log. |
| 7 or more | Also profiles the initialization of every model. |
Files rotate once they exceed Log.MaxSize (for example '1M'), keeping Log.MaxHistory copies if Log.KeepHistory is true. Other framework logs: not_found.log (URLs without a controller), rewrite.log (with Debug.Rewrite ≥ 5), i18n.log (missing translation keys) and db_query.log.
Profiler
It measures how long each stage of the request takes and writes it to tmp/logs/profile.log. It is enabled with Debug.Level ≥ 2 and:
'Debug' => [
'Level' => 2,
'Profiler' => ['Enabled' => true, 'lowThreshold' => 0.001], // only logs what takes more than 1 ms
],
The core already measures routing, the dispatcher, the controller hooks, every SQL query and rendering. To measure your own code:
$result = Profiler::profileCallable(function () {
return buildReport();
}, 'Monthly report');
Quick debugging
dump_var($variable); // prints the variable (and its methods if it is an object) and stops
dump_var($variable, false); // without stopping
echo TMProductos::where('prd_destacado', '1')->compile(); // the SQL that would run
Koshkil::dumpConfig(); // the whole configuration
RewriteManager::dumpRules(); // active rewrite rules
?php_info=1 on any URL shows phpinfo(). Disable or restrict it in production.