Simply record the time from entering `main` to start listening sockets.
for (const auto & protocol : protocols)
    {
        std::vector<std::string> hosts;
        if (config.has("protocols." + protocol + ".host"))
            hosts.push_back(config.getString("protocols." + protocol + ".host"));
        else
            hosts = listen_hosts;
        for (const auto & host : hosts)
        {
            std::string conf_name = "protocols." + protocol;
            std::string prefix = conf_name + ".";
            if (!config.has(prefix + "port"))
                continue;
            std::string description {"<undefined> protocol"};
            if (config.has(prefix + "description"))
                description = config.getString(prefix + "description");
            std::string port_name = prefix + "port";
            bool is_secure = false;
            auto stack = buildProtocolStackFromConfig(config, protocol, http_params, async_metrics, is_secure);
            if (stack->empty())
                throw Exception(ErrorCodes::INVALID_CONFIG_PARAMETER, "Protocol '{}' stack empty", protocol);
            createServer(config, host, port_name.c_str(), listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter
            {
                Poco::Net::ServerSocket socket;
                auto address = socketBindListen(config, socket, host, port, is_secure);
                socket.setReceiveTimeout(settings.receive_timeout);
                socket.setSendTimeout(settings.send_timeout);
                return ProtocolServerAdapter(
                    host,
                    port_name.c_str(),