Page MenuHomePhabricator

D7560.id17055.diff
No OneTemporary

D7560.id17055.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -193,6 +193,7 @@
'PhutilLipsumContextFreeGrammar' => 'grammar/PhutilLipsumContextFreeGrammar.php',
'PhutilLock' => 'filesystem/PhutilLock.php',
'PhutilLockException' => 'filesystem/PhutilLockException.php',
+ 'PhutilLogfileChannel' => 'channel/PhutilLogfileChannel.php',
'PhutilLunarPhase' => 'utils/PhutilLunarPhase.php',
'PhutilLunarPhaseTestCase' => 'utils/__tests__/PhutilLunarPhaseTestCase.php',
'PhutilMarkupEngine' => 'markup/PhutilMarkupEngine.php',
@@ -369,6 +370,7 @@
'phutil_is_hiphop_runtime' => 'utils/utils.php',
'phutil_is_utf8' => 'utils/utf8.php',
'phutil_is_windows' => 'utils/utils.php',
+ 'phutil_loggable_string' => 'utils/utils.php',
'phutil_passthru' => 'future/exec/execx.php',
'phutil_safe_html' => 'markup/render.php',
'phutil_split_lines' => 'utils/utils.php',
@@ -560,6 +562,7 @@
'PhutilLexerSyntaxHighlighter' => 'PhutilSyntaxHighlighter',
'PhutilLipsumContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhutilLockException' => 'Exception',
+ 'PhutilLogfileChannel' => 'PhutilChannelChannel',
'PhutilLunarPhaseTestCase' => 'PhutilTestCase',
'PhutilMarkupTestCase' => 'PhutilTestCase',
'PhutilMetricsChannel' => 'PhutilChannelChannel',
Index: src/channel/PhutilLogfileChannel.php
===================================================================
--- /dev/null
+++ src/channel/PhutilLogfileChannel.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * A @{class:PhutilChannelChannel} which wraps some other channel and writes
+ * data passed over it to a log file.
+ */
+final class PhutilLogfileChannel extends PhutilChannelChannel {
+
+ private $logfile;
+
+ public function setLogfile($path) {
+ $this->logfile = fopen($path, 'a');
+ $this->log('--- '.getmypid().' ---');
+ return $this;
+ }
+
+ public function read() {
+ $buffer = parent::read();
+ $this->log('>>> '.phutil_loggable_string($buffer));
+ return $buffer;
+ }
+
+ public function write($message) {
+ $this->log('<<< '.phutil_loggable_string($message));
+ return parent::write($message);
+ }
+
+ private function log($message) {
+ if ($this->logfile) {
+ fwrite($this->logfile, $message."\n");
+ }
+ }
+
+}
Index: src/utils/__tests__/PhutilUtilsTestCase.php
===================================================================
--- src/utils/__tests__/PhutilUtilsTestCase.php
+++ src/utils/__tests__/PhutilUtilsTestCase.php
@@ -443,6 +443,24 @@
}
}
+ public function testLoggableString() {
+ $this->assertEqual(
+ "",
+ phutil_loggable_string(""));
+
+ $this->assertEqual(
+ "a\\nb",
+ phutil_loggable_string("a\nb"));
+
+ $this->assertEqual(
+ "a\\x01b",
+ phutil_loggable_string("a\x01b"));
+
+ $this->assertEqual(
+ "a\\x1Fb",
+ phutil_loggable_string("a\x1Fb"));
+ }
+
}
Index: src/utils/utils.php
===================================================================
--- src/utils/utils.php
+++ src/utils/utils.php
@@ -883,3 +883,37 @@
exit($status);
}
+
+/**
+ * Converts a string to a loggable one, with unprintables and newlines escaped.
+ *
+ * @param string Any string.
+ * @return string String with control and newline characters escaped, suitable
+ * for printing on a single log line.
+ */
+function phutil_loggable_string($string) {
+ $result = '';
+
+ static $c_map = array(
+ "\\" => '\\\\',
+ "\n" => '\\n',
+ "\r" => '\\r',
+ "\t" => '\\t',
+ );
+
+ for ($ii = 0; $ii < strlen($string); $ii++) {
+ $c = $string[$ii];
+ if (isset($c_map[$c])) {
+ $result .= $c_map[$c];
+ } else {
+ $o = ord($c);
+ if ($o < 0x20 || $o == 0x7F) {
+ $result .= '\\x'.sprintf('%02X', $o);
+ } else {
+ $result .= $c;
+ }
+ }
+ }
+
+ return $result;
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 2, 9:02 AM (18 h, 21 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7216586
Default Alt Text
D7560.id17055.diff (3 KB)

Event Timeline