public function run(array $args = []): string
    {
        $result = [
            'name' => $this->name,
            'status' => 'ok',
            'components' => [],
            'dependencies' => $this->dependencies
        ];

        foreach ($this->checks as $service => $check) {
            $checkArgs = isset($args[$service]) ? $args[$service] : [];

            if (is_string($check) && class_exists($check)) {
                $check = new $check($checkArgs);

                if (!($check instanceof BaseCheck)) {
                    throw new \Exception($service . ' check must be derived from Ackly\\Health\\Check\\BaseCheck');
                }

                $serviceStatus = $check->run();
            } else {
                $serviceStatus = call_user_func_array($check, $checkArgs);
            }

            if (!($serviceStatus instanceof CheckResult)) {
                throw new \Exception('Each health check must return instance of Ackly\\Health\\CheckResult');
            }

            if ($serviceStatus->status == 'warning' && $result['status'] == 'ok') {
                $result['status'] = 'warning';
            }

            if ($serviceStatus->status == 'error') {
                $result['status'] = 'error';
            }

            $result['components'][$service] = array_merge(['name' => $service], $serviceStatus->toArray());
        }

        if (empty($result['components'])) {
            unset($result['components']);
        }

        $this->result = $result;

        /** @var Formatter\IFormatter $formatter */
        $formatter = new $this->formatter();
        return $formatter->format($result);
    }