void Socket::DebugSocket()

in src/brpc/socket.cpp [2316:2589]


void Socket::DebugSocket(std::ostream& os, SocketId id) {
    SocketUniquePtr ptr;
    int ret = Socket::AddressFailedAsWell(id, &ptr);
    if (ret < 0) {
        os << "SocketId=" << id << " is invalid or recycled";
        return;
    } else if (ret > 0) {
        // NOTE: Printing a broken socket w/o HC is informational for
        // debugging referential issues.
        // if (ptr->_health_check_interval_s <= 0) {
        //     // Sockets without HC will soon be destroyed
        //     os << "Invalid SocketId=" << id;
        //     return;
        // }
        os << "# This is a broken Socket\n";
    }
    const uint64_t vref = ptr->versioned_ref();
    size_t npipelined = 0;
    size_t idsizes[4];
    size_t nidsize = 0;
    {
        BAIDU_SCOPED_LOCK(ptr->_pipeline_mutex);
        if (ptr->_pipeline_q) {
            npipelined = ptr->_pipeline_q->size();
        }
    }
    {
        BAIDU_SCOPED_LOCK(ptr->_id_wait_list_mutex);
        if (bthread::get_sizes) {
            nidsize = bthread::get_sizes(
                &ptr->_id_wait_list, idsizes, arraysize(idsizes));
        }
    }
    const int preferred_index = ptr->preferred_index();
    SharedPart* sp = ptr->GetSharedPart();
    os << "version=" << VersionOfVRef(vref);
    if (sp) {
        os << "\nshared_part={\n  ref_count=" << sp->ref_count()
           << "\n  socket_pool=";
        SocketPool* pool = sp->socket_pool.load(butil::memory_order_consume);
        if (pool) {
            os << '[';
            std::vector<SocketId> pooled_sockets;
            pool->ListSockets(&pooled_sockets, 0);
            for (size_t i = 0; i < pooled_sockets.size(); ++i) {
                if (i) {
                    os << ' ';
                }
                os << pooled_sockets[i];
            }
            os << "]\n  numfree="
               << pool->_numfree.load(butil::memory_order_relaxed)
               << "\n  numinflight="
               << pool->_numinflight.load(butil::memory_order_relaxed);
        } else {
            os << "null";
        }
        os << "\n  creator_socket=" << sp->creator_socket_id
           << "\n  in_size=" << sp->in_size.load(butil::memory_order_relaxed)
           << "\n  in_num_messages=" << sp->in_num_messages.load(butil::memory_order_relaxed)
           << "\n  out_size=" << sp->out_size.load(butil::memory_order_relaxed)
           << "\n  out_num_messages=" << sp->out_num_messages.load(butil::memory_order_relaxed)
           << "\n}";
    }
    const int fd = ptr->_fd.load(butil::memory_order_relaxed);
    os << "\nnref=" << NRefOfVRef(vref) - 1
        //                                ^
        // minus the ref of current callsite(calling PrintSocket)
       << "\nnevent=" << ptr->_nevent.load(butil::memory_order_relaxed)
       << "\nfd=" << fd
       << "\ntos=" << ptr->_tos
       << "\nreset_fd_to_now=" << butil::gettimeofday_us() - ptr->_reset_fd_real_us << "us"
       << "\nremote_side=" << ptr->_remote_side
       << "\nlocal_side=" << ptr->_local_side
       << "\non_et_events=" << (void*)ptr->_on_edge_triggered_events
       << "\nuser=" << ShowObject(ptr->_user)
       << "\nthis_id=" << ptr->id()
       << "\npreferred_index=" << preferred_index;
    InputMessenger* messenger = dynamic_cast<InputMessenger*>(ptr->user());
    if (messenger != NULL) {
        os << " (" << messenger->NameOfProtocol(preferred_index) << ')';
    }
    const int64_t cpuwide_now = butil::cpuwide_time_us();
    os << "\nhc_count=" << ptr->_hc_count
       << "\navg_input_msg_size=" << ptr->_avg_msg_size
        // NOTE: We're assuming that butil::IOBuf.size() is thread-safe, it is now
        // however it's not guaranteed.
       << "\nread_buf=" << ptr->_read_buf.size()
       << "\nlast_read_to_now=" << cpuwide_now - ptr->_last_readtime_us << "us"
       << "\nlast_write_to_now=" << cpuwide_now - ptr->_last_writetime_us << "us"
       << "\novercrowded=" << ptr->_overcrowded;
    os << "\nid_wait_list={";
    for (size_t i = 0; i < nidsize; ++i) {
        if (i) {
            os << ' ';
        }
        os << idsizes[i];
    }
    os << '}';
    Destroyable* const parsing_context = ptr->parsing_context();
    Describable* parsing_context_desc = dynamic_cast<Describable*>(parsing_context);
    if (parsing_context_desc) {
        os << "\nparsing_context=" << butil::class_name_str(*parsing_context) << '{';
        DescribeOptions opt;
        opt.verbose = true;
        IndentingOStream os2(os, 2);
        parsing_context_desc->Describe(os2, opt);
        os << '}';
    } else {
        os << "\nparsing_context=" << ShowObject(parsing_context);
    }
    const SSLState ssl_state = ptr->ssl_state();
    os << "\npipeline_q=" << npipelined
       << "\nhc_interval_s=" << ptr->_health_check_interval_s
       << "\nis_hc_related_ref_held=" << ptr->_is_hc_related_ref_held
       << "\nninprocess=" << ptr->_ninprocess.load(butil::memory_order_relaxed)
       << "\nauth_flag_error=" << ptr->_auth_flag_error.load(butil::memory_order_relaxed)
       << "\nauth_id=" << ptr->_auth_id.value
       << "\nauth_context=" << ptr->_auth_context
       << "\nlogoff_flag=" << ptr->_logoff_flag.load(butil::memory_order_relaxed)
       << "\n_additional_ref_status="
       << ptr->additional_ref_status()
       << "\ntotal_streams_buffer_size="
       << ptr->_total_streams_unconsumed_size.load(butil::memory_order_relaxed)
       << "\nninflight_app_health_check="
       << ptr->_ninflight_app_health_check.load(butil::memory_order_relaxed)
       << "\nagent_socket_id=";
    const SocketId asid = ptr->_agent_socket_id.load(butil::memory_order_relaxed);
    if (asid != INVALID_SOCKET_ID) {
        os << asid;
    } else {
        os << "(none)";
    }
    os << "\ncid=" << ptr->_correlation_id
       << "\nwrite_head=" << ptr->_write_head.load(butil::memory_order_relaxed)
       << "\nssl_state=" << SSLStateToString(ssl_state);
    const SocketSSLContext* ssl_ctx = ptr->_ssl_ctx.get();
    if (ssl_ctx) {
        os << "\ninitial_ssl_ctx=" << ssl_ctx->raw_ctx;
        if (!ssl_ctx->sni_name.empty()) {
            os << "\nsni_name=" << ssl_ctx->sni_name;
        }
    }
    if (ssl_state == SSL_CONNECTED) {
        os << "\nssl_session={\n  ";
        Print(os, ptr->_ssl_session, "\n  ");
        os << "\n}";
    }

    os << "\nis_wirte_shutdown=" << ptr->_is_write_shutdown;

    {
        int keepalive = 0;
        socklen_t len = sizeof(keepalive);
        if (getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, &len) == 0) {
            os << "\nkeepalive=" << keepalive;
        }
    }

    {
        int keepidle = 0;
        socklen_t len = sizeof(keepidle);
#if defined(OS_MACOSX)
        if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepidle, &len) == 0) {
            os << "\ntcp_keepalive_time=" << keepidle;
        }
#elif defined(OS_LINUX)
        if (getsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &keepidle, &len) == 0) {
            os << "\ntcp_keepalive_time=" << keepidle;
        }
#endif
    }

    {
        int keepintvl = 0;
        socklen_t len = sizeof(keepintvl);
#if defined(OS_MACOSX)
        if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, &len) == 0) {
            os << "\ntcp_keepalive_intvl=" << keepintvl;
        }
#elif defined(OS_LINUX)
        if (getsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &keepintvl, &len) == 0) {
            os << "\ntcp_keepalive_intvl=" << keepintvl;
        }
#endif
    }

    {
        int keepcnt = 0;
        socklen_t len = sizeof(keepcnt);
#if defined(OS_MACOSX)
        if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, &len) == 0) {
            os << "\ntcp_keepalive_probes=" << keepcnt;
        }
#elif defined(OS_LINUX)
        if (getsockopt(fd, SOL_TCP, TCP_KEEPCNT, &keepcnt, &len) == 0) {
            os << "\ntcp_keepalive_probes=" << keepcnt;
        }
#endif
    }

#if defined(OS_LINUX)
    {
        int tcp_user_timeout = 0;
        socklen_t len = sizeof(tcp_user_timeout);
        if (getsockopt(fd, SOL_TCP, TCP_USER_TIMEOUT, &tcp_user_timeout, &len) == 0) {
            os << "\ntcp_user_timeout=" << tcp_user_timeout;
        }
    }
#endif

#if defined(OS_MACOSX)
    struct tcp_connection_info ti;
    socklen_t len = sizeof(ti);
    if (fd >= 0 && getsockopt(fd, IPPROTO_TCP, TCP_CONNECTION_INFO, &ti, &len) == 0) {
        os << "\ntcpi={\n  state=" << (uint32_t)ti.tcpi_state
           << "\n  snd_wscale=" << (uint32_t)ti.tcpi_snd_wscale
           << "\n  rcv_wscale=" << (uint32_t)ti.tcpi_rcv_wscale
           << "\n  options=" << (uint32_t)ti.tcpi_options
           << "\n  flags=" << (uint32_t)ti.tcpi_flags
           << "\n  rto=" << ti.tcpi_rto
           << "\n  maxseg=" << ti.tcpi_maxseg
           << "\n  snd_ssthresh=" << ti.tcpi_snd_ssthresh
           << "\n  snd_cwnd=" << ti.tcpi_snd_cwnd
           << "\n  snd_wnd=" << ti.tcpi_snd_wnd
           << "\n  snd_sbbytes=" << ti.tcpi_snd_sbbytes
           << "\n  rcv_wnd=" << ti.tcpi_rcv_wnd
           << "\n  srtt=" << ti.tcpi_srtt
           << "\n  rttvar=" << ti.tcpi_rttvar
           << "\n}";
    }
#elif defined(OS_LINUX)
    struct tcp_info ti;
    socklen_t len = sizeof(ti);
    if (fd >= 0 && getsockopt(fd, SOL_TCP, TCP_INFO, &ti, &len) == 0) {
        os << "\ntcpi={\n  state=" << (uint32_t)ti.tcpi_state
           << "\n  ca_state=" << (uint32_t)ti.tcpi_ca_state
           << "\n  retransmits=" << (uint32_t)ti.tcpi_retransmits
           << "\n  probes=" << (uint32_t)ti.tcpi_probes
           << "\n  backoff=" << (uint32_t)ti.tcpi_backoff
           << "\n  options=" << (uint32_t)ti.tcpi_options
           << "\n  snd_wscale=" << (uint32_t)ti.tcpi_snd_wscale
           << "\n  rcv_wscale=" << (uint32_t)ti.tcpi_rcv_wscale
           << "\n  rto=" << ti.tcpi_rto
           << "\n  ato=" << ti.tcpi_ato
           << "\n  snd_mss=" << ti.tcpi_snd_mss
           << "\n  rcv_mss=" << ti.tcpi_rcv_mss
           << "\n  unacked=" << ti.tcpi_unacked
           << "\n  sacked=" << ti.tcpi_sacked
           << "\n  lost=" << ti.tcpi_lost
           << "\n  retrans=" << ti.tcpi_retrans
           << "\n  fackets=" << ti.tcpi_fackets
           << "\n  last_data_sent=" << ti.tcpi_last_data_sent
           << "\n  last_ack_sent=" << ti.tcpi_last_ack_sent
           << "\n  last_data_recv=" << ti.tcpi_last_data_recv
           << "\n  last_ack_recv=" << ti.tcpi_last_ack_recv
           << "\n  pmtu=" << ti.tcpi_pmtu
           << "\n  rcv_ssthresh=" << ti.tcpi_rcv_ssthresh
           << "\n  rtt=" << ti.tcpi_rtt  // smoothed
           << "\n  rttvar=" << ti.tcpi_rttvar
           << "\n  snd_ssthresh=" << ti.tcpi_snd_ssthresh
           << "\n  snd_cwnd=" << ti.tcpi_snd_cwnd
           << "\n  advmss=" << ti.tcpi_advmss
           << "\n  reordering=" << ti.tcpi_reordering
           << "\n}";
    }
#endif
#if BRPC_WITH_RDMA
    if (ptr->_rdma_state == RDMA_ON && ptr->_rdma_ep) {
        ptr->_rdma_ep->DebugInfo(os);
    }
#endif
    { os << "\nbthread_tag=" << ptr->_io_event.bthread_tag(); }
}