Feature Request
Add a first-class trace() convenience method (and corresponding TRACE constant / level name) to Phalcon\Logger\Logger, Phalcon\Logger\LoggerInterface, and Phalcon\Logger\AbstractLogger.
Current Behaviour
AbstractLogger exposes a CUSTOM = 8 constant and maps it to the level name "custom" in getLevels(). No named trace() method exists on Logger or LoggerInterface. Consumers who need trace-level logging must either:
- Subclass
Logger, add a TRACE constant, override getLevels() to rename 8 → "trace", and add the trace() method themselves; or
- Call
$logger->log(8, $message) with a magic integer and receive log entries labelled "custom" rather than "trace".
Both workarounds are friction the framework should absorb.
Expected Behaviour
// Constant available on AbstractLogger
AbstractLogger::TRACE; // = 8
// Level name returned as "trace", not "custom"
$logger->trace('Detailed wire-level response', ['body' => $body]);
// → level name in output: "trace"
Proposed Changes
phalcon/Logger/AbstractLogger.zep
- Rename (or alias)
CUSTOM → TRACE:
const TRACE = 8; // rename; keep CUSTOM as a deprecated alias if needed for BC
- Update
getLevels() to map 8 → "trace":
- Update
setLogLevel() fallback (self::CUSTOM → self::TRACE) and logLevel default comment.
phalcon/Logger/Logger.zep
Add the convenience method:
/**
* Extra-verbose diagnostic output.
*
* Use for high-frequency, fine-grained events such as raw socket frames,
* HTTP response bodies, or internal state transitions that are too noisy
* for DEBUG.
*
* @param string $message
* @param array $context
*
* @return void
* @throws Exception
* @throws LoggerException
*/
public function trace(string message, array context = []) -> void
{
this->addMessage(self::TRACE, message, context);
}
phalcon/Logger/LoggerInterface.zep
Add the corresponding interface method:
/**
* Extra-verbose diagnostic output.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function trace(string message, array context = []) -> void;
Motivation
- Trace is a well-established level. Log4j, SLF4J, Monolog, and most mature logging frameworks reserve a level below DEBUG for extra-verbose output (raw frames, full HTTP bodies, tight-loop state).
CUSTOM with no semantic name is not a substitute.
"custom" is not a usable level name in production. Structured log aggregators (e.g. Loki, ELK) filter by level string. "custom" cannot be mapped to any known severity in those systems; "trace" can.
- Subclassing just to rename a level is unnecessary friction. The workaround requires overriding both
getLevels() (to rename the label) and adding the trace() method, despite the underlying integer slot already existing in the framework.
Real-World Reference
The following is the exact override currently required in downstream projects (TwistersFury\Phalcon\Shared\Logger\Logger) to work around the missing native support:
class Logger extends PhalconLogger
{
const TRACE = 8; // CUSTOM
private levels = [
2 : "alert",
1 : "critical",
7 : "debug",
0 : "emergency",
3 : "error",
6 : "info",
5 : "notice",
4 : "warning",
8 : "trace" // rename CUSTOM → trace
];
public function trace(string message, array context = []) -> void
{
this->addMessage(self::CUSTOM, message, context);
}
protected function getLevels() -> array
{
return this->levels;
}
}
This override would become unnecessary if the three changes above were made to the framework.
Backwards Compatibility
Keeping CUSTOM = 8 as a deprecated alias alongside TRACE = 8 (both pointing to the same integer) avoids breaking any existing code that references AbstractLogger::CUSTOM. The only observable change in output is the level label in log entries changing from "custom" to "trace" — applications that currently rely on the literal string "custom" in log output would need to update their log-parsing rules, but that is expected for a meaningful rename.
Feature Request
Add a first-class
trace()convenience method (and correspondingTRACEconstant / level name) toPhalcon\Logger\Logger,Phalcon\Logger\LoggerInterface, andPhalcon\Logger\AbstractLogger.Current Behaviour
AbstractLoggerexposes aCUSTOM = 8constant and maps it to the level name"custom"ingetLevels(). No namedtrace()method exists onLoggerorLoggerInterface. Consumers who need trace-level logging must either:Logger, add aTRACEconstant, overridegetLevels()to rename8 → "trace", and add thetrace()method themselves; or$logger->log(8, $message)with a magic integer and receive log entries labelled"custom"rather than"trace".Both workarounds are friction the framework should absorb.
Expected Behaviour
Proposed Changes
phalcon/Logger/AbstractLogger.zepCUSTOM→TRACE:getLevels()to map8 → "trace":setLogLevel()fallback (self::CUSTOM→self::TRACE) andlogLeveldefault comment.phalcon/Logger/Logger.zepAdd the convenience method:
phalcon/Logger/LoggerInterface.zepAdd the corresponding interface method:
Motivation
CUSTOMwith no semantic name is not a substitute."custom"is not a usable level name in production. Structured log aggregators (e.g. Loki, ELK) filter by level string."custom"cannot be mapped to any known severity in those systems;"trace"can.getLevels()(to rename the label) and adding thetrace()method, despite the underlying integer slot already existing in the framework.Real-World Reference
The following is the exact override currently required in downstream projects (
TwistersFury\Phalcon\Shared\Logger\Logger) to work around the missing native support:This override would become unnecessary if the three changes above were made to the framework.
Backwards Compatibility
Keeping
CUSTOM = 8as a deprecated alias alongsideTRACE = 8(both pointing to the same integer) avoids breaking any existing code that referencesAbstractLogger::CUSTOM. The only observable change in output is the level label in log entries changing from"custom"to"trace"— applications that currently rely on the literal string"custom"in log output would need to update their log-parsing rules, but that is expected for a meaningful rename.