O framework PHP por trás do SitioYa

Documentação do Koshkil

Serviços

Cache, logs e depuração

Cache

O CacheManager entrega um motor de cache por domínio de uso. Cada domínio pode usar seu próprio motor, caminho e tempo de vida.

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

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

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

Métodos disponíveis em todos os motores (CacheInterface):

Método Uso
get($chave, $padrao = null) Lê um valor.
set($chave, $valor, $ttl = 0) Grava (0 = o TTL do domínio).
has($chave), delete($chave)
getMultiple(), setMultiple(), deleteMultiple() Operações em grupo.
increment($chave), decrement($chave) Contadores.
clear() / flush() Esvazia o domínio / o motor.
getStats() Estatísticas.

Configuração

// config/cache.php (resumo)
$CONFIG = [
    'Cache' => [
        'enabled'   => true,
        'default'   => 'file',             // 'file', 'redis' ou '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],
        ],
    ],
];
Domínio O que o framework guarda
models A estrutura de cada tabela, invalidada quando o arquivo do modelo muda.
i18n Os JSON de tradução já lidos.
plugins Configuração e permissões de cada plugin.
query Livre para consultas próprias (desativado por padrão).

O motor null não guarda nada: serve para testes ou para desativar um domínio. Para o Redis é preciso a extensão redis do PHP.

Limpar e pré-carregar

  • No painel, Sistema → Caché mostra estatísticas por domínio e permite limpar ou pré-carregar.
  • Pelo terminal, depois do deploy:
./app/bin/warm-cache.sh                     # traduções, modelos e plugins
php app/bin/warm-cache.php --domain=i18n --verbose
php app/bin/warm-cache.php --force          # apaga antes de pré-carregar
  • ?reset_plugins em qualquer URL lê de novo a configuração dos plugins.
  • Os arquivos de tmp/cache/ podem ser apagados sem risco: são gerados de novo automaticamente.

Logs

KoshkilLog grava em tmp/logs/<nome>.log. Com Debug.Level em 0 nada é gravado.

KoshkilLog::error('Falha na cobrança', ['pedido' => 123]);    // error.log
KoshkilLog::warning('Estoque baixo', $producto->record());    // warning.log
KoshkilLog::info('Pedido confirmado');                        // info.log
KoshkilLog::debug('Resposta do fornecedor', $json);           // debug.log
KoshkilLog::addLog('pagamentos', 'Webhook recebido', $_POST); // pagamentos.log
Debug.Level Efeito
0 Sem logs.
1 Logs; nos dados anexados, senhas e o número completo de cartões são mascarados.
2 Logs; senhas e números de cartão são mascarados.
3 Logs; números de cartão são mascarados.
6 ou mais Também registra cada consulta SQL em debug.log.
7 ou mais Também perfila a inicialização de cada modelo.

Os arquivos são rotacionados ao passar de Log.MaxSize (por exemplo '1M'), mantendo Log.MaxHistory cópias se Log.KeepHistory for true. Outros logs do framework: not_found.log (URLs sem controlador), rewrite.log (com Debug.Rewrite ≥ 5), i18n.log (chaves de tradução ausentes) e db_query.log.

Profiler

Mede quanto demora cada etapa da requisição e grava em tmp/logs/profile.log. É ativado com Debug.Level ≥ 2 e:

'Debug' => [
    'Level'    => 2,
    'Profiler' => ['Enabled' => true, 'lowThreshold' => 0.001],  // só registra o que demora mais de 1 ms
],

O núcleo já mede o roteamento, o dispatcher, os hooks do controlador, cada consulta SQL e a renderização. Para medir o seu próprio código:

$resultado = Profiler::profileCallable(function () {
    return gerarRelatorio();
}, 'Relatório mensal');

Depuração rápida

dump_var($variavel);          // mostra a variável (e seus métodos, se for um objeto) e encerra
dump_var($variavel, false);   // sem encerrar
echo TMProductos::where('prd_destacado', '1')->compile();   // SQL que seria executado
Koshkil::dumpConfig();        // toda a configuração
RewriteManager::dumpRules();  // regras de reescrita ativas

?php_info=1 em qualquer URL mostra o phpinfo(). Desative-o ou restrinja-o em produção.