public function setup( $priority = 100 ) {

		if ( did_action( self::ACTION_SETUP ) ) {
			return $this;
		}

		// We use WONOLOG_DISABLE instead of WONOLOG_ENABLE so that not defined (default) means enabled.
		$disable_by_env = filter_var( getenv( 'WONOLOG_DISABLE' ), FILTER_VALIDATE_BOOLEAN );

		/**
		 * Filters whether to completely disable Wonolog.
		 *
		 * @param bool $disable
		 */
		if ( apply_filters( self::FILTER_DISABLE, $disable_by_env ) ) {
			return $this;
		}

		/**
		 * Fires right before Wonolog is set up.
		 */
		do_action( self::ACTION_SETUP );

		$processor_registry = new ProcessorsRegistry();
		$handlers_registry  = new HandlersRegistry( $processor_registry );
		$subscriber         = new LogActionSubscriber( new Channels( $handlers_registry, $processor_registry ) );
		$listener           = [ $subscriber, 'listen' ];

		add_action( LOG, $listener, $priority, PHP_INT_MAX );

		foreach ( Logger::getLevels() as $level => $level_code ) {
			// $level_code is from 100 (DEBUG) to 600 (EMERGENCY) this makes hook priority based on level priority
			add_action( LOG . '.' . strtolower( $level ), $listener, $priority + ( 601 - $level_code ), PHP_INT_MAX );
		}

		add_action( 'muplugins_loaded', [ HookListenersRegistry::class, 'initialize' ], PHP_INT_MAX );

		/**
		 * Fires right after Wonolog has been set up.
		 */
		do_action( self::ACTION_LOADED );

		return $this;
	}