77use Toolkit \Cli \Cli ;
88use Toolkit \Cli \ColorTag ;
99use function date ;
10+ use function debug_backtrace ;
1011use function implode ;
1112use function is_numeric ;
1213use function json_encode ;
1314use function sprintf ;
1415use function strpos ;
1516use function trim ;
17+ use const DEBUG_BACKTRACE_IGNORE_ARGS ;
1618use const JSON_PRETTY_PRINT ;
1719use const JSON_UNESCAPED_SLASHES ;
1820use const PHP_EOL ;
@@ -92,22 +94,29 @@ public static function newApp(
9294 return new Application ($ config , $ input , $ output );
9395 }
9496
97+ /**
98+ * @var int
99+ */
100+ public static $ traceIndex = 1 ;
101+
95102 /**
96103 * @param int $level
97104 * @param string $format
98105 * @param mixed ...$args
99106 */
100107 public static function logf (int $ level , string $ format , ...$ args ): void
101108 {
109+ $ datetime = date ('Y/m/d H:i:s ' );
102110 $ levelName = self ::LEVEL_NAMES [$ level ] ?? 'INFO ' ;
103111 $ colorName = self ::LEVEL2TAG [$ level ] ?? 'info ' ;
104112
105- $ taggedName = ColorTag::add ($ levelName , $ colorName );
113+ $ message = strpos ($ format , '% ' ) > 0 ? sprintf ($ format , ...$ args ) : $ format ;
114+ $ tagName = ColorTag::add ($ levelName , $ colorName );
106115
107- $ datetime = date ( ' Y/m/d H:i:s ' );
108- $ message = strpos ( $ format , ' % ' ) > 0 ? sprintf ( $ format , ... $ args ) : $ format ;
116+ $ backtrace = debug_backtrace ( DEBUG_BACKTRACE_IGNORE_ARGS , self :: $ traceIndex + 2 );
117+ $ position = self :: formatBacktrace ( $ backtrace , self :: $ traceIndex ) ;
109118
110- self ::writef ('%s [%s] %s ' , $ datetime , $ taggedName , $ message );
119+ self ::writef ('%s [%s] [%s] %s ' , $ datetime , $ tagName , $ position , $ message );
111120 }
112121
113122 /**
@@ -124,13 +133,14 @@ public static function logf(int $level, string $format, ...$args): void
124133 * 'coId' => 12,
125134 * ]
126135 */
127- public static function log (string $ msg , array $ data = [], int $ level = self :: VERB_DEBUG , array $ opts = []): void
136+ public static function log (int $ level , string $ msg , array $ data = [], array $ opts = []): void
128137 {
129138 $ levelName = self ::LEVEL_NAMES [$ level ] ?? 'INFO ' ;
130139 $ colorName = self ::LEVEL2TAG [$ level ] ?? 'info ' ;
131140 $ taggedName = ColorTag::add ($ levelName , $ colorName );
132141
133142 $ userOpts = [];
143+ $ datetime = date ('Y/m/d H:i:s ' );
134144 foreach ($ opts as $ n => $ v ) {
135145 if (is_numeric ($ n ) || strpos ($ n , '_ ' ) === 0 ) {
136146 $ userOpts [] = "[ $ v] " ;
@@ -140,8 +150,31 @@ public static function log(string $msg, array $data = [], int $level = self::VER
140150 }
141151
142152 $ optString = $ userOpts ? ' ' . implode (' ' , $ userOpts ) : '' ;
143- $ dataString = $ data ? PHP_EOL . json_encode ($ data , JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) : '' ;
153+ $ dataString = $ data ? json_encode ($ data , JSON_UNESCAPED_SLASHES ) : '' ;
154+
155+ $ backtrace = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS , self ::$ traceIndex + 2 );
156+ $ position = self ::formatBacktrace ($ backtrace , self ::$ traceIndex );
157+
158+ self ::writef ('%s [%s] [%s]%s %s %s ' , $ datetime , $ taggedName , $ position , $ optString , trim ($ msg ), $ dataString );
159+ }
160+
161+ /**
162+ * @param array $traces
163+ * @param int $index
164+ *
165+ * @return string
166+ */
167+ private static function formatBacktrace (array $ traces , int $ index ): string
168+ {
169+ $ position = 'unknown ' ;
170+
171+ if (isset ($ traces [$ index +1 ])) {
172+ $ tInfo = $ traces [$ index ];
173+ $ prev = $ traces [$ index +1 ];
174+
175+ $ position = sprintf ('%s.%s:%d ' , $ prev ['class ' ], $ prev ['function ' ] ?? 'UNKNOWN ' , $ tInfo ['line ' ]);
176+ }
144177
145- self :: writef ( ' %s [%s]%s %s %s ' , date ( ' Y/m/d H:i:s ' ), $ taggedName , $ optString , trim ( $ msg ), $ dataString );
178+ return ColorTag:: add ( $ position , ' green ' );
146179 }
147180}
0 commit comments