Simply record the time from entering `main` to start listening sockets.
if (!config.has(prefix + "impl"))
            break;
        conf_name = "protocols." + config.getString(prefix + "impl");
        prefix = conf_name + ".";
        if (!pset.insert(conf_name).second)
            throw Exception(ErrorCodes::INVALID_CONFIG_PARAMETER, "Protocol '{}' configuration contains a loop on '{}'", protocol, conf_name);
    }
    return stack;
}
HTTPContextPtr Server::httpContext() const
{
    return std::make_shared<HTTPContext>(context());
}
void Server::createServers(
    Poco::Util::AbstractConfiguration & config,
    const Strings & listen_hosts,
    const Strings & interserver_listen_hosts,
    bool listen_try,
    Poco::ThreadPool & server_pool,
    AsynchronousMetrics & async_metrics,
    std::vector<ProtocolServerAdapter> & servers,
    bool start_servers)
{
    const Settings & settings = global_context->getSettingsRef();
    Poco::Timespan keep_alive_timeout(config.getUInt("keep_alive_timeout", 10), 0);
    Poco::Net::HTTPServerParams::Ptr http_params = new Poco::Net::HTTPServerParams;
    http_params->setTimeout(settings.http_receive_timeout);
    http_params->setKeepAliveTimeout(keep_alive_timeout);
    Poco::Util::AbstractConfiguration::Keys protocols;
    config.keys("protocols", protocols);