owncloud/core

View on GitHub
lib/private/Log/CommandLogger.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
/**
 * @author Thomas Müller <thomas.mueller@tmit.eu>
 *
 * @copyright Copyright (c) 2018 ownCloud GmbH
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace OC\Log;

use OCP\ILogger;
use OCP\Util;
use Symfony\Component\Console\Output\OutputInterface;

class CommandLogger implements ILogger {
    /** @var OutputInterface */
    private $output;

    /**
     * CommandLogger constructor.
     *
     * @param OutputInterface $output
     */
    public function __construct(OutputInterface $output) {
        $this->output = $output;
    }

    /**
     * System is unusable.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function emergency($message, array $context = []) {
        $this->log(Util::FATAL, $message, $context);
    }

    /**
     * Action must be taken immediately.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function alert($message, array $context = []) {
        $this->log(Util::ERROR, $message, $context);
    }

    /**
     * Critical conditions.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function critical($message, array $context = []) {
        $this->log(Util::ERROR, $message, $context);
    }

    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function error($message, array $context = []) {
        $this->log(Util::ERROR, $message, $context);
    }

    /**
     * Exceptional occurrences that are not errors.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function warning($message, array $context = []) {
        $this->log(Util::WARN, $message, $context);
    }

    /**
     * Normal but significant events.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function notice($message, array $context = []) {
        $this->log(Util::INFO, $message, $context);
    }

    /**
     * Interesting events.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function info($message, array $context = []) {
        $this->log(Util::ERROR, $message, $context);
    }

    /**
     * Detailed debug information.
     *
     * @param string $message
     * @param array $context
     * @return void
     * @since 7.0.0
     */
    public function debug($message, array $context = []) {
        $this->log(Util::DEBUG, $message, $context);
    }

    /**
     * Logs with an arbitrary level.
     *
     * @param mixed $level
     * @param string $message
     * @param array $context
     * @return mixed
     * @since 7.0.0
     */
    public function log($level, $message, array $context = []) {
        $minLevel = Util::INFO;
        $verbosity = $this->output->getVerbosity();
        if ($verbosity === OutputInterface::VERBOSITY_DEBUG) {
            $minLevel = Util::DEBUG;
        }
        if ($verbosity === OutputInterface::VERBOSITY_QUIET) {
            $minLevel = Util::ERROR;
        }
        if ($level < $minLevel) {
            return;
        }

        // interpolate $message as defined in PSR-3
        $replace = [];
        foreach ($context as $key => $val) {
            $replace['{' . $key . '}'] = $val;
        }

        // interpolate replacement values into the message and return
        $message = \strtr($message, $replace);
        $style = ($level > 2) ?'error' : 'info';

        $this->output->writeln("<$style>$message</$style>");
    }

    /**
     * Logs an exception very detailed
     * An additional message can we written to the log by adding it to the
     * context.
     *
     * <code>
     * $logger->logException($ex, [
     *     'message' => 'Exception during cron job execution'
     * ]);
     * </code>
     *
     * @param \Exception | \Throwable $exception
     * @param array $context
     * @return void
     * @since 8.2.0
     */
    public function logException($exception, array $context = []) {
        $exception = [
            'Exception' => \get_class($exception),
            'Message' => $exception->getMessage(),
            'Code' => $exception->getCode(),
            'Trace' => $exception->getTraceAsString(),
            'File' => $exception->getFile(),
            'Line' => $exception->getLine(),
        ];
        $exception['Trace'] = \preg_replace('!(login|checkPassword|updatePrivateKeyPassword)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']);
        $msg = isset($context['message']) ? $context['message'] : 'Exception';
        $msg .= ': ' . \json_encode($exception);
        $this->error($msg, $context);
    }
}