Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/gallery.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Paroz <github@oparoz.com>2015-01-09 21:39:13 +0300
committerOlivier Paroz <github@oparoz.com>2015-01-09 21:39:13 +0300
commit31dc01f931cc35d0a2aa7fa23a9a978aaf94949c (patch)
treed9589c501ab8597f36c4b9fbfa8938a55006450d /utility
parent8a2c8586d982a8a5258bad9464edb195050d1ecd (diff)
Improved normalizer
* Its own class * Only JSON encodes the end result * Max depth for object recursion is set to 2 * Max number of array elements to log is set to 20
Diffstat (limited to 'utility')
-rw-r--r--utility/normalizer.php167
-rw-r--r--utility/smarterlogger.php154
2 files changed, 193 insertions, 128 deletions
diff --git a/utility/normalizer.php b/utility/normalizer.php
new file mode 100644
index 00000000..287345c6
--- /dev/null
+++ b/utility/normalizer.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * ownCloud - galleryplus
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Olivier Paroz <owncloud@interfasys.ch>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @copyright Olivier Paroz 2015
+ * @copyright Jordi Boggiano 2014-2015
+ */
+
+namespace OCA\GalleryPlus\Utility;
+
+/**
+ * Lets us call the main logger without having to add the context at every
+ * request
+ *
+ * @package OCA\GalleryPlus\Utility
+ */
+class Normalizer {
+
+ /**
+ * Converts Objects, Arrays and Exceptions to String
+ *
+ * @param $data
+ * @param int $depth
+ *
+ * @return string|array
+ */
+ public function normalize($data, $depth = 0) {
+ if (null === $data || is_scalar($data)) {
+ /*// utf8_encode only works for Latin1, we may have ANSI strings
+ if (is_string($data)) {
+ $data = mb_convert_encoding($data, "UTF-8");
+ }*/
+
+ return $data;
+ }
+
+ $traversable = $this->normalizeTraversable($data, $depth);
+ if ($traversable) {
+ return $traversable;
+ }
+
+ $object = $this->normalizeObject($data, $depth);
+ if ($object) {
+ return $object;
+ }
+
+ $resource = $this->normalizeResource($data);
+ if ($resource) {
+ return $resource;
+ }
+
+ return '[unknown(' . gettype($data) . ')]';
+ }
+
+ /**
+ * Converts each element of a traversable variable to String
+ *
+ * @param $data
+ * @param int $depth
+ *
+ * @return array|null
+ */
+ private function normalizeTraversable($data, $depth = 0) {
+ if (is_array($data) || $data instanceof \Traversable) {
+ $maxArrayRecursion = 20; //
+ $normalized = array();
+ $count = 1;
+
+ foreach ($data as $key => $value) {
+ if ($count++ >= $maxArrayRecursion) {
+ $normalized['...'] =
+ 'Over '
+ . $maxArrayRecursion
+ . ' items, aborting normalization';
+ break;
+ }
+ $normalized[$key] = $this->normalize($value, $depth);
+ }
+
+ return $normalized;
+ }
+
+ return null;
+ }
+
+ /**
+ * Converts an Object to String
+ *
+ * @param mixed $data
+ * @param int $depth
+ *
+ * @return array|null
+ */
+ private function normalizeObject($data, $depth) {
+ if (is_object($data)) {
+ if ($data instanceof \Exception) {
+ return $this->normalizeException($data);
+ }
+
+ // We don't need to go too deep in the recursion
+ $maxObjectRecursion = 2;
+ $response = $data;
+ $arrayObject = new \ArrayObject($data);
+ $serializedObject = $arrayObject->getArrayCopy();
+
+ if ($depth < $maxObjectRecursion) {
+ $depth++;
+ $response = $this->normalize($serializedObject, $depth);
+ }
+
+ // Don't convert to json here as we would double encode
+ return array(
+ sprintf("[object] (%s)", get_class($data)),
+ $response
+ );
+ }
+
+ return null;
+ }
+
+ /**
+ * Converts an Exception to String
+ *
+ * @param \Exception $exception
+ *
+ * @return string
+ */
+ private function normalizeException(\Exception $exception) {
+ $data = array(
+ 'class' => get_class($exception),
+ 'message' => $exception->getMessage(),
+ 'code' => $exception->getCode(),
+ 'file' => $exception->getFile() . ':' . $exception->getLine(),
+ );
+ $trace = $exception->getTraceAsString();
+ $data['trace'][] = $trace;
+
+ $previous = $exception->getPrevious();
+ if ($previous) {
+ $data['previous'] = $this->normalizeException($previous);
+ }
+
+ return $data;
+ }
+
+ /**
+ * Converts a resource to a String
+ *
+ * @param $data
+ *
+ * @return string|null
+ */
+ private function normalizeResource($data) {
+ if (is_resource($data)) {
+ return "[resource] " . substr((string)$data, 0, 40);
+ }
+
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/utility/smarterlogger.php b/utility/smarterlogger.php
index 4cc2e11c..4899b18e 100644
--- a/utility/smarterlogger.php
+++ b/utility/smarterlogger.php
@@ -6,12 +6,8 @@
* later. See the COPYING file.
*
* @author Olivier Paroz <owncloud@interfasys.ch>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Jordi Boggiano <j.boggiano@seld.be>
*
* @copyright Olivier Paroz 2015
- * @copyright Bart Visscher 2013-2015
- * @copyright Jordi Boggiano 2014-2015
*/
namespace OCA\GalleryPlus\Utility;
@@ -22,7 +18,7 @@ use OCP\ILogger;
* Lets us call the main logger without having to add the context at every
* request
*
- * @package OCA\GalleryPlus\Middleware
+ * @package OCA\GalleryPlus\Utility
*/
class SmarterLogger implements ILogger {
@@ -30,19 +26,26 @@ class SmarterLogger implements ILogger {
* @type ILogger
*/
private $logger;
+ /**
+ * @type Normalizer
+ */
+ private $normalizer;
/***
* Constructor
*
* @param string $appName
* @param ILogger $logger
+ * @param Normalizer $normalizer
*/
public function __construct(
$appName,
- ILogger $logger
+ ILogger $logger,
+ Normalizer $normalizer
) {
$this->appName = $appName;
$this->logger = $logger;
+ $this->normalizer = $normalizer;
}
/**
@@ -143,7 +146,8 @@ class SmarterLogger implements ILogger {
}
/**
- * Normalises a message and logs it with an arbitrary level.
+ * Converts the received log message to string before sending it to the
+ * ownCloud logger
*
* @param mixed $level
* @param string $message
@@ -152,140 +156,34 @@ class SmarterLogger implements ILogger {
* @return mixed
*/
public function log($level, $message, array $context = array()) {
- // interpolate $message as defined in PSR-3
- $replace = array();
- foreach ($context as $key => $val) {
- // Allows us to dump arrays, objects and exceptions to the log
- $val = $this->normalize($val);
- $replace['{' . $key . '}'] = $val;
- }
-
- // interpolate replacement values into the message and return
- $message = strtr($message, $replace);
-
- $this->logger->log(
- $level, $message,
- array(
- 'app' => $this->appName
- )
- );
-
- }
+ array_walk($context, [$this, 'contextNormalizer']);
- /**
- * Converts Objects, Arrays and Exceptions to String
- *
- * @param $data
- *
- * @return string
- */
- private function normalize($data) {
- if (null === $data || is_scalar($data)) {
- return $data;
+ if (!isset($context['app'])) {
+ $context['app'] = $this->appName;
}
- if ($this->normalizeTraversable($data)) {
- return $this->normalizeTraversable($data);
- }
-
- if ($this->normalizeObject($data)) {
- return $this->normalizeObject($data);
- }
-
- if (is_resource($data)) {
- return '[resource]';
- }
-
- return '[unknown(' . gettype($data) . ')]';
+ $this->logger->log($level, $message, $context);
}
/**
- * Converts a traversable variable to String
+ * Normalises the context parameters and JSON encodes and cleans up the
+ * result
*
- * @param $data
- *
- * @return string
- */
- private function normalizeTraversable($data) {
- if (is_array($data) || $data instanceof \Traversable) {
- $normalized = array();
- $count = 1;
- foreach ($data as $key => $value) {
- if ($count >= 1000) {
- $normalized['...'] =
- 'Over 1000 items, aborting normalization';
- break;
- }
- $normalized[$key] = $this->normalize($value);
- }
-
- //return $normalized;
- return $this->toJson($normalized);
- }
-
- return null;
- }
-
- /**
- * Converts an Object to String
+ * @todo: could maybe do a better job removing slashes
*
- * @param $data
+ * @param array $data
*
* @return string
*/
- private function normalizeObject($data) {
- if (is_object($data)) {
- if ($data instanceof \Exception) {
- return $this->normalizeException($data);
- }
-
- $arrayObject = new \ArrayObject($data);
- $serializedObject = $arrayObject->getArrayCopy();
-
- return sprintf(
- "[object] (%s: %s)", get_class($data),
- $this->toJson($serializedObject)
+ private function contextNormalizer(&$data) {
+ $data = $this->normalizer->normalize($data);
+ if (!is_string($data)) {
+ $data = @json_encode(
+ $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
+ // Removing null byte and double slashes from object properties
+ $data = str_replace(['\\u0000', '\\\\'], ["", "\\"], $data);
}
-
- return null;
}
- /**
- * Converts an Exception to String
- *
- * @param \Exception $exception
- *
- * @return string
- */
- private function normalizeException(\Exception $exception) {
- $data = array(
- 'class' => get_class($exception),
- 'message' => $exception->getMessage(),
- 'file' => $exception->getFile() . ':' . $exception->getLine(),
- );
- $trace = $exception->getTraceAsString();
- $data['trace'][] = $trace;
-
- $previous = $exception->getPrevious();
- if ($previous) {
- $data['previous'] = $this->normalizeException($previous);
- }
-
- return $this->toJson($data);
- }
-
- /**
- * JSON encodes data
- *
- * @param $data
- *
- * @return string
- */
- private function toJson($data) {
- // suppress json_encode errors since it's twitchy with some inputs
- return @json_encode(
- $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
- );
- }
} \ No newline at end of file