Simply record the time from entering `main` to start listening sockets.
{
        size_t max_size = config().getUInt64("max_temporary_data_on_disk_size", 0);
        global_context->setTemporaryStorageInCache(temporary_cache, max_size);
    }
    else
    {
        std::string temporary_path = config().getString("tmp_path", path / "tmp/");
        size_t max_size = config().getUInt64("max_temporary_data_on_disk_size", 0);
        global_context->setTemporaryStoragePath(temporary_path, max_size);
    }
    /** Directory with 'flags': files indicating temporary settings for the server set by system administrator.
      * Flags may be cleared automatically after being applied by the server.
      * Examples: do repair of local data; clone all replicated tables from replica.
      */
    {
        auto flags_path = path / "flags/";
        fs::create_directories(flags_path);
        global_context->setFlagsPath(flags_path);
    }
    /** Directory with user provided files that are usable by 'file' table function.
      */
    {
        std::string user_files_path = config().getString("user_files_path", path / "user_files/");
        global_context->setUserFilesPath(user_files_path);
        fs::create_directories(user_files_path);
    }
    {
        std::string dictionaries_lib_path = config().getString("dictionaries_lib_path", path / "dictionaries_lib/");
        global_context->setDictionariesLibPath(dictionaries_lib_path);
        fs::create_directories(dictionaries_lib_path);