public static function getCallable(Logger $logger, $type, $maxMessageLength)
	{
		return function (MessageInterface $message) use ($logger, $type, $maxMessageLength) {
			$startMessage = null;
			if ($message instanceof RequestInterface) {
				$startMessage = sprintf(
					'Proxy %s start: HTTP/%s %s %s',
					$type,
					$message->getProtocolVersion(),
					$message->getMethod(),
					$message->getRequestTarget()
				);
			} elseif ($message instanceof ResponseInterface) {
				$startMessage = sprintf(
					'Proxy %s start: HTTP/%s %s %s',
					$type,
					$message->getProtocolVersion(),
					$message->getStatusCode(),
					$message->getReasonPhrase()
				);
			}

			if (!is_null($startMessage)) {
				$logger->log(Logger::INFO, $startMessage);
			}

			// output headers
			foreach ($message->getHeaders() as $name => $value) {
				$logger->log(
					Logger::INFO,
					sprintf(
						"Proxy %s header: %s => %s",
						$type,
						$name,
						implode(', ', $value)
					)
				);
			}

			$body = $message->getBody();
			if (strlen($body) > $maxMessageLength) {
				$body = substr($body, 0, $maxMessageLength).'[TRUNCATED]';
			}

			$logger->log(
				Logger::INFO,
				sprintf(
					"Proxy %s body: %s",
					$type,
					$body
				)
			);

			if (!is_null($message) && $message->getBody()->isSeekable()) {
				$message->getBody()->rewind();
			}
			return $message;
		};
	}