void ConnectionsService::PrintConnections()

in src/brpc/builtin/connections_service.cpp [111:328]


void ConnectionsService::PrintConnections(
    std::ostream& os, const std::vector<SocketId>& conns,
    bool use_html, const Server* server, bool is_channel_conn) const {
    if (conns.empty()) {
        return;
    }
    if (use_html) {
        os << "<table class=\"gridtable sortable\" border=\"1\"><tr>"
            "<th>CreatedTime</th>"
            "<th>RemoteSide</th>";
        if (is_channel_conn) {
            os << "<th>Local</th>"
                "<th>RecentErr</th>"
                "<th>nbreak</th>";
        }
        os << "<th>SSL</th>"
            "<th>Protocol</th>"
            "<th>fd</th>"
            "<th>InBytes/s</th>"
            "<th>In/s</th>"
            "<th>InBytes/m</th>"
            "<th>In/m</th>"
            "<th>OutBytes/s</th>"
            "<th>Out/s</th>"
            "<th>OutBytes/m</th>"
            "<th>Out/m</th>"
            "<th>Rtt/Var(ms)</th>"
            "<th>SocketId</th>"
            "</tr>\n";
    } else {
        os << "CreatedTime               |RemoteSide         |";
        if (is_channel_conn) {
            os << "Local|RecentErr|nbreak|";
        }
        os << "SSL|Protocol    |fd   |"
            "InBytes/s|In/s  |InBytes/m |In/m    |"
            "OutBytes/s|Out/s |OutBytes/m|Out/m   |"
            "Rtt/Var(ms)|SocketId\n";
    }

    const char* const bar = (use_html ? "</td><td>" : "|");
    SocketStat stat;
    std::string nshead_service_name; // shared in following for iterations.
    std::vector<SocketId> first_id;
    for (size_t i = 0; i < conns.size(); ++i) {
        const SocketId socket_id = conns[i];
        SocketUniquePtr ptr;
        bool failed = false;
        if (Socket::Address(socket_id, &ptr) != 0) {
            int ret = Socket::AddressFailedAsWell(socket_id, &ptr);
            if (ret < 0) {
                continue;
            } else if (ret > 0) {
                if (!ptr->HCEnabled()) {
                    // Sockets without HC will soon be destroyed
                    continue;
                }
                failed = true;
            }
        }            

        if (use_html) {
            os << "<tr><td>";
        }
        if (failed) {
            os << min_width("Broken", 26) << bar
               << min_width(NameOfPoint(ptr->remote_side()), 19) << bar;
            if (is_channel_conn) {
                os << min_width(ptr->local_side().port, 5) << bar
                   << min_width(ptr->recent_error_count(), 10) << bar
                   << min_width(ptr->isolated_times(), 7) << bar;
            }
            os << min_width("-", 3) << bar
               << min_width("-", 12) << bar
               << min_width("-", 5) << bar
               << min_width("-", 9) << bar
               << min_width("-", 6) << bar
               << min_width("-", 10) << bar
               << min_width("-", 8) << bar
               << min_width("-", 10) << bar
               << min_width("-", 6) << bar
               << min_width("-", 10) << bar
               << min_width("-", 8) << bar
               << min_width("-", 11) << bar;
        } else {
            {
                SocketUniquePtr agent_sock;
                if (ptr->PeekAgentSocket(&agent_sock) == 0) {
                    ptr.swap(agent_sock);
                }
            }
            // Get name of the protocol. In principle we can dynamic_cast the
            // socket user to InputMessenger but I'm not sure if that's a bit
            // slow (because we have many connections here).
            int pref_index = ptr->preferred_index();
            SocketUniquePtr first_sub;
            int pooled_count = -1;
            if (ptr->HasSocketPool()) {
                int numfree = 0;
                int numinflight = 0;
                if (ptr->GetPooledSocketStats(&numfree, &numinflight)) {
                    pooled_count = numfree + numinflight;
                }
                // Check preferred_index of any pooled sockets.
                ptr->ListPooledSockets(&first_id, 1);
                if (!first_id.empty()) {
                    Socket::Address(first_id[0], &first_sub);
                }
            }
            const char* pref_prot = "-";
            if (ptr->user() == server->_am) {
                pref_prot = server->_am->NameOfProtocol(pref_index);
                // Special treatment for nshead services. Notice that
                // pref_index is comparable to ProtocolType after r31951
                if (pref_index == (int)PROTOCOL_NSHEAD &&
                    server->options().nshead_service != NULL) {
                    if (nshead_service_name.empty()) {
                        nshead_service_name = BriefName(butil::class_name_str(
                                *server->options().nshead_service));
                    }
                    pref_prot = nshead_service_name.c_str();
                }
            } else if (ptr->CreatedByConnect()) {
                pref_prot = get_client_side_messenger()->NameOfProtocol(pref_index);
            }
            if (strcmp(pref_prot, "unknown") == 0) {
                // Show unknown protocol as - to be consistent with other columns.
                pref_prot = "-";
            } else if (strcmp(pref_prot, "h2") == 0) {
                if (!ptr->is_ssl()) {
                    pref_prot = "h2c";
                }
            }
            ptr->GetStat(&stat);
            PrintRealDateTime(os, ptr->_reset_fd_real_us);
            int rttfd = ptr->fd();
            if (rttfd < 0 && first_sub != NULL) {
                rttfd = first_sub->fd();
            }

            bool got_rtt = false;
            uint32_t srtt = 0;
            uint32_t rtt_var = 0;
            // get rtt
#if defined(OS_LINUX)
            struct tcp_info ti;
            socklen_t len = sizeof(ti);
            if (0 == getsockopt(rttfd, SOL_TCP, TCP_INFO, &ti, &len)) {
                got_rtt = true;
                srtt = ti.tcpi_rtt;
                rtt_var = ti.tcpi_rttvar;
            }
#elif defined(OS_MACOSX)
            struct tcp_connection_info ti;
            socklen_t len = sizeof(ti);
            if (0 == getsockopt(rttfd, IPPROTO_TCP, TCP_CONNECTION_INFO, &ti, &len)) {
                got_rtt = true;
                srtt = ti.tcpi_srtt;
                rtt_var = ti.tcpi_rttvar;
            }
#endif
            char rtt_display[32];
            if (got_rtt) {
                snprintf(rtt_display, sizeof(rtt_display), "%.1f/%.1f",
                         srtt / 1000.0, rtt_var / 1000.0);
            } else {
                strcpy(rtt_display, "-");
            }
            os << bar << min_width(NameOfPoint(ptr->remote_side()), 19) << bar;
            if (is_channel_conn) {
                if (ptr->local_side().port > 0) {
                    os << min_width(ptr->local_side().port, 5) << bar;
                } else {
                    os << min_width("-", 5) << bar;
                }
                os << min_width(ptr->recent_error_count(), 10) << bar
                   << min_width(ptr->isolated_times(), 7) << bar;
            }
            os << SSLStateToYesNo(ptr->ssl_state(), use_html) << bar;
            char protname[32];
            if (pooled_count < 0) {
                snprintf(protname, sizeof(protname), "%s", pref_prot);
            } else {
                snprintf(protname, sizeof(protname), "%s*%d", pref_prot,
                         pooled_count);
            }
            os << min_width(protname, 12) << bar;
            if (ptr->fd() >= 0) {
                os << min_width(ptr->fd(), 5) << bar;
            } else {
                os << min_width("-", 5) << bar;
            }
            os << min_width(stat.in_size_s, 9) << bar
               << min_width(stat.in_num_messages_s, 6) << bar
               << min_width(stat.in_size_m, 10) << bar
               << min_width(stat.in_num_messages_m, 8) << bar
               << min_width(stat.out_size_s, 10) << bar
               << min_width(stat.out_num_messages_s, 6) << bar
               << min_width(stat.out_size_m, 10) << bar
               << min_width(stat.out_num_messages_m, 8) << bar
               << min_width(rtt_display, 11) << bar;
        }

        if (use_html) {
            os << "<a href=\"/sockets/" << socket_id << "\">" << socket_id
               << "</a>";
        } else {
            os << socket_id;
        }
        if (use_html) {
            os << "</td></tr>";
        }
        os << '\n';
    }
    if (use_html) {
        os << "</table>\n";
    }
}