El framework PHP detrás de SitioYa

Documentación de Koshkil

Servicios

Caché, logs y depuración

Caché

CacheManager entrega un motor de caché por dominio de uso. Cada dominio puede usar su propio motor, ruta y tiempo de vida.

Koshkil::Uses('sys.cache.CacheManager');

$cache = CacheManager::engine('query');          // o 'default', 'models', 'i18n', 'plugins'…
$clave = 'productos:destacados';

$lista = $cache->get($clave);
if ($lista === null) {
    $lista = TMProductos::where('prd_destacado', '1')->getAsArray();
    $cache->set($clave, $lista, 300);            // 5 minutos
}

Métodos disponibles en todos los motores (CacheInterface):

Método Uso
get($clave, $defecto = null) Lee un valor.
set($clave, $valor, $ttl = 0) Guarda (0 = el TTL del dominio).
has($clave), delete($clave)
getMultiple(), setMultiple(), deleteMultiple() Operaciones en grupo.
increment($clave), decrement($clave) Contadores.
clear() / flush() Vacía el dominio / el motor.
getStats() Estadísticas.

Configuración

// config/cache.php (resumen)
$CONFIG = [
    'Cache' => [
        'enabled'   => true,
        'default'   => 'file',             // 'file', 'redis' o '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],
        ],
    ],
];
Dominio Qué guarda el framework
models La estructura de cada tabla, invalidada cuando cambia el archivo del modelo.
i18n Los JSON de traducción ya leídos.
plugins Configuración y permisos de cada plugin.
query Libre para consultas propias (desactivado por defecto).

El motor null no guarda nada: sirve para pruebas o para desactivar un dominio. Para Redis se necesita la extensión redis de PHP.

Limpiar y precargar

  • En el panel, Sistema → Caché muestra estadísticas por dominio y permite limpiar o precargar.
  • Desde la terminal, después de desplegar:
./app/bin/warm-cache.sh                     # traducciones, modelos y plugins
php app/bin/warm-cache.php --domain=i18n --verbose
php app/bin/warm-cache.php --force          # borra antes de precargar
  • ?reset_plugins en cualquier URL vuelve a leer la configuración de los plugins.
  • Los archivos de tmp/cache/ se pueden borrar sin riesgo: se regeneran solos.

Logs

KoshkilLog escribe en tmp/logs/<nombre>.log. Con Debug.Level en 0 no se escribe nada.

KoshkilLog::error('No se pudo cobrar', ['pedido' => 123]);   // error.log
KoshkilLog::warning('Stock bajo', $producto->record());      // warning.log
KoshkilLog::info('Pedido confirmado');                       // info.log
KoshkilLog::debug('Respuesta del proveedor', $json);         // debug.log
KoshkilLog::addLog('pagos', 'Webhook recibido', $_POST);     // pagos.log
Debug.Level Efecto
0 Sin logs.
1 Logs; en los datos adjuntos se enmascaran contraseñas y el número completo de tarjetas.
2 Logs; se enmascaran contraseñas y números de tarjeta.
3 Logs; se enmascaran números de tarjeta.
6 o más Además registra cada consulta SQL en debug.log.
7 o más Además perfila la inicialización de cada modelo.

Los archivos rotan al superar Log.MaxSize (por ejemplo '1M'), conservando Log.MaxHistory copias si Log.KeepHistory es true. Otros logs del framework: not_found.log (URLs sin controlador), rewrite.log (con Debug.Rewrite ≥ 5), i18n.log (claves de traducción faltantes) y db_query.log.

Perfilador

Mide cuánto tarda cada etapa de la petición y lo escribe en tmp/logs/profile.log. Se activa con Debug.Level ≥ 2 y:

'Debug' => [
    'Level'    => 2,
    'Profiler' => ['Enabled' => true, 'lowThreshold' => 0.001],  // solo registra lo que tarda más de 1 ms
],

El núcleo ya mide el ruteo, el dispatcher, los hooks del controlador, cada consulta SQL y el renderizado. Para medir tu propio código:

$resultado = Profiler::profileCallable(function () {
    return calcularReporte();
}, 'Reporte mensual');

Depuración rápida

dump_var($variable);          // muestra la variable (y sus métodos si es un objeto) y termina
dump_var($variable, false);   // sin terminar
echo TMProductos::where('prd_destacado', '1')->compile();   // SQL que se ejecutaría
Koshkil::dumpConfig();        // toda la configuración
RewriteManager::dumpRules();  // reglas de reescritura activas

?php_info=1 en cualquier URL muestra phpinfo(). Desactivalo o restringilo en producción.