The logger can be injected from the ServerContainer:

namespace OCA\MyApp\AppInfo;

use \OCP\AppFramework\App;
use \OCA\MyApp\Service\AuthorService;

class Application extends App {

    public function __construct(array $urlParams=[]){
        parent::__construct('myapp', $urlParams);

        $container = $this->getContainer();

         * Controllers
        $container->registerService('AuthorService', function($c) {
            return new AuthorService(

        $container->registerService('Logger', function($c) {
            return $c->query('ServerContainer')->getLogger();

Once injected, it can then be used in the following way:

namespace OCA\MyApp\Service;

use \OCP\ILogger;

class AuthorService {

    private $logger;
    private $appName;

    public function __construct(ILogger $logger, $appName){
        $this->logger = $logger;
        $this->appName = $appName;

    public function log($message) {
        $this->logger->error($message, ['app' => $this->appName]);


The following methods are available:

  • emergency

  • alert

  • critical

  • error

  • warning

  • notice

  • info

  • debug

Which Logging Level Should You Use?

When considering which logging level to use, please refer to this guide from IG:


Information that is useful during development. Usually very chatty, and will not show in production.


Information you will need to debug production issues.

WARN (warning)

Someone in the team will have to investigate what happened, but it can wait until tomorrow.


Oh-oh, call the fireman! This needs to be investigated now!

Usage Examples

The following example shows how to log a simple text string, to the level of info. Methods are available which match the other seven log levels.


// Log a simple, text message
$this->logger->info('Entity has changed state.');

The following example shows how to log a text string that makes use of string interpolation, and additional JSON fields.


// Log a message with string interpolation and additional content
$this->logger->info('Entity {entityName} has changed state to {newState}', [
    // these are used for text substitution in the above message
    'entityName' => 'X',
    'newState' => 'state2',
    // these will appear as additional JSON fields in the log entries
    'extraFields' => [
        'entityName' => 'X',
        'oldState' => 'state1',
        'newState' => 'state2',
        'entityOwner' => 'someuser',