5 * Contains \Drush\Log\Logger.
7 * This is the actual Logger for Drush that is responsible
8 * for logging messages.
10 * This logger is designed such that it can be provided to
11 * other libraries that log to a Psr\Log\LoggerInterface.
12 * As such, it takes responsibility for passing log messages
13 * to backend invoke, as necessary (c.f. drush_backend_packet()).
15 * Drush supports all of the required log levels from Psr\Log\LogLevel,
16 * and also defines its own. See Drush\Log\LogLevel.
18 * Those who may wish to change the way logging works in Drush
19 * should therefore NOT attempt to replace this logger with their
20 * own LoggerInterface, as it will not work. It would be okay
21 * to extend Drush\Log\Logger, or perhaps we could provide a way
22 * to set an output I/O object here, in case output redirection
23 * was the only thing that needed to be swapped out.
28 use Drush\Log\LogLevel;
29 use Psr\Log\AbstractLogger;
31 class Logger extends AbstractLogger {
33 public function log($level, $message, array $context = array()) {
34 // Convert to old $entry array for b/c calls
36 $entry['type'] = $level;
37 $entry['message'] = $message;
38 if (!isset($entry['memory'])) {
39 $entry['memory'] = memory_get_usage();
42 // Drush\Log\Logger should take over all of the responsibilities
43 // of drush_log, including caching the log messages and sending
44 // log messages along to backend invoke.
45 // TODO: move these implementations inside this class.
46 $log =& drush_get_context('DRUSH_LOG', array());
48 if ($level != LogLevel::DEBUG_NOTIFY) {
49 drush_backend_packet('log', $entry);
52 if (drush_get_context('DRUSH_NOCOLOR')) {
58 $red = "\033[31;40m\033[1m[%s]\033[0m";
59 $yellow = "\033[1;33;40m\033[1m[%s]\033[0m";
60 $green = "\033[1;32;40m\033[1m[%s]\033[0m";
63 $verbose = drush_get_context('DRUSH_VERBOSE');
64 $debug = drush_get_context('DRUSH_DEBUG');
65 $debugnotify = drush_get_context('DRUSH_DEBUG_NOTIFY');
68 case LogLevel::WARNING :
69 case LogLevel::CANCEL :
70 $type_msg = sprintf($yellow, $level);
72 case 'failed' : // Obsolete; only here in case contrib is using it.
73 case LogLevel::EMERGENCY : // Not used by Drush
74 case LogLevel::ALERT : // Not used by Drush
75 case LogLevel::ERROR :
76 $type_msg = sprintf($red, $level);
79 case 'completed' : // Obsolete; only here in case contrib is using it.
80 case LogLevel::SUCCESS :
81 case 'status': // Obsolete; only here in case contrib is using it.
82 // In quiet mode, suppress progress messages
83 if (drush_get_context('DRUSH_QUIET')) {
86 $type_msg = sprintf($green, $level);
88 case LogLevel::NOTICE :
89 case 'message' : // Obsolete; only here in case contrib is using it.
92 // print nothing. exit cleanly.
95 $type_msg = sprintf("[%s]", $level);
97 case LogLevel::DEBUG_NOTIFY :
98 $level = LogLevel::DEBUG; // Report 'debug', handle like 'preflight'
99 case LogLevel::PREFLIGHT :
101 // print nothing unless --debug AND --verbose. exit cleanly.
104 $type_msg = sprintf("[%s]", $level);
106 case LogLevel::BOOTSTRAP :
107 case LogLevel::DEBUG :
110 // print nothing. exit cleanly.
113 $type_msg = sprintf("[%s]", $level);
117 // When running in backend mode, log messages are not displayed, as they will
118 // be returned in the JSON encoded associative array.
119 if (drush_get_context('DRUSH_BACKEND')) {
123 $columns = drush_get_context('DRUSH_COLUMNS', 80);
126 // Append timer and memory values.
128 $timer = sprintf('[%s sec, %s]', round($entry['timestamp']-DRUSH_REQUEST_TIME, 2), drush_format_size($entry['memory']));
129 $entry['message'] = $entry['message'] . ' ' . $timer;
132 $width[0] = ($columns - 11);
134 $format = sprintf("%%-%ds%%%ds", $width[0], $width[1]);
136 // Place the status message right aligned with the top line of the error message.
137 $message = wordwrap($entry['message'], $width[0]);
138 $lines = explode("\n", $message);
139 $lines[0] = sprintf($format, $lines[0], $type_msg);
140 $message = implode("\n", $lines);
141 drush_print($message, 0, STDERR);