Example #1
0
        private static void AddCommonDetail(
            List <Tuple <string, string> > data,
            StringBuilder sb,
            Message message,
            ConnectionMultiplexer multiplexer,
            ServerEndPoint server
            )
        {
            if (message != null)
            {
                message.TryGetHeadMessages(out var now, out var next);
                if (now != null)
                {
                    Add(data, sb, "Message-Current", "active", multiplexer.IncludeDetailInExceptions ? now.CommandAndKey : now.Command.ToString());
                }
                if (next != null)
                {
                    Add(data, sb, "Message-Next", "next", multiplexer.IncludeDetailInExceptions ? next.CommandAndKey : next.Command.ToString());
                }
            }

            // Add server data, if we have it
            if (server != null && message != null)
            {
                var bs = server.GetBridgeStatus(message.IsForSubscriptionBridge ? ConnectionType.Subscription: ConnectionType.Interactive);

                switch (bs.Connection.ReadStatus)
                {
                case PhysicalConnection.ReadStatus.CompletePendingMessageAsync:
                case PhysicalConnection.ReadStatus.CompletePendingMessageSync:
                    sb.Append(" ** possible thread-theft indicated; see https://stackexchange.github.io/StackExchange.Redis/ThreadTheft ** ");
                    break;
                }
                Add(data, sb, "OpsSinceLastHeartbeat", "inst", bs.MessagesSinceLastHeartbeat.ToString());
                Add(data, sb, "Queue-Awaiting-Write", "qu", bs.BacklogMessagesPending.ToString());
                Add(data, sb, "Queue-Awaiting-Response", "qs", bs.Connection.MessagesSentAwaitingResponse.ToString());
                Add(data, sb, "Active-Writer", "aw", bs.IsWriterActive.ToString());
                if (bs.BacklogMessagesPending != 0)
                {
                    Add(data, sb, "Backlog-Writer", "bw", bs.BacklogStatus.ToString());
                }
                if (bs.Connection.ReadStatus != PhysicalConnection.ReadStatus.NA)
                {
                    Add(data, sb, "Read-State", "rs", bs.Connection.ReadStatus.ToString());
                }
                if (bs.Connection.WriteStatus != PhysicalConnection.WriteStatus.NA)
                {
                    Add(data, sb, "Write-State", "ws", bs.Connection.WriteStatus.ToString());
                }

                if (bs.Connection.BytesAvailableOnSocket >= 0)
                {
                    Add(data, sb, "Inbound-Bytes", "in", bs.Connection.BytesAvailableOnSocket.ToString());
                }
                if (bs.Connection.BytesInReadPipe >= 0)
                {
                    Add(data, sb, "Inbound-Pipe-Bytes", "in-pipe", bs.Connection.BytesInReadPipe.ToString());
                }
                if (bs.Connection.BytesInWritePipe >= 0)
                {
                    Add(data, sb, "Outbound-Pipe-Bytes", "out-pipe", bs.Connection.BytesInWritePipe.ToString());
                }

                if (multiplexer.StormLogThreshold >= 0 && bs.Connection.MessagesSentAwaitingResponse >= multiplexer.StormLogThreshold && Interlocked.CompareExchange(ref multiplexer.haveStormLog, 1, 0) == 0)
                {
                    var log = server.GetStormLog(message);
                    if (string.IsNullOrWhiteSpace(log))
                    {
                        Interlocked.Exchange(ref multiplexer.haveStormLog, 0);
                    }
                    else
                    {
                        Interlocked.Exchange(ref multiplexer.stormLogSnapshot, log);
                    }
                }
                Add(data, sb, "Server-Endpoint", "serverEndpoint", server.EndPoint.ToString().Replace("Unspecified/", ""));
            }
            Add(data, sb, "Multiplexer-Connects", "mc", $"{multiplexer._connectAttemptCount}/{multiplexer._connectCompletedCount}/{multiplexer._connectionCloseCount}");
            Add(data, sb, "Manager", "mgr", multiplexer.SocketManager?.GetState());

            Add(data, sb, "Client-Name", "clientName", multiplexer.ClientName);
            if (message != null)
            {
                var hashSlot = message.GetHashSlot(multiplexer.ServerSelectionStrategy);
                // only add keyslot if its a valid cluster key slot
                if (hashSlot != ServerSelectionStrategy.NoSlot)
                {
                    Add(data, sb, "Key-HashSlot", "PerfCounterHelperkeyHashSlot", message.GetHashSlot(multiplexer.ServerSelectionStrategy).ToString());
                }
            }
            int busyWorkerCount = PerfCounterHelper.GetThreadPoolStats(out string iocp, out string worker, out string workItems);

            Add(data, sb, "ThreadPool-IO-Completion", "IOCP", iocp);
            Add(data, sb, "ThreadPool-Workers", "WORKER", worker);
            if (workItems != null)
            {
                Add(data, sb, "ThreadPool-Items", "POOL", workItems);
            }
            data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString()));

            if (multiplexer.IncludePerformanceCountersInExceptions)
            {
                Add(data, sb, "Local-CPU", "Local-CPU", PerfCounterHelper.GetSystemCpuPercent());
            }

            Add(data, sb, "Version", "v", GetLibVersion());
        }