Ejemplo n.º 1
0
        /// <summary>
        /// print out some periodic information on server statistics
        /// </summary>
        /// <param name="state"></param>
        public static void PrintStats(object state)
        {
            try
            {
                //Don't enable this line unless you have memory issues and
                //need more details in memory usage
                //GC.Collect();

                long newTick = DateTime.Now.Ticks;
                long time    = newTick - m_lastMeasureTick;
                m_lastMeasureTick = newTick;
                time /= 10000000L;
                if (time < 1)
                {
                    log.Warn("Time has not changed since last call of PrintStats");
                    time = 1;                     // prevent division by zero?
                }
                long inRate     = (Statistics.BytesIn - m_lastBytesIn) / time;
                long outRate    = (Statistics.BytesOut - m_lastBytesOut) / time;
                long inPckRate  = (Statistics.PacketsIn - m_lastPacketsIn) / time;
                long outPckRate = (Statistics.PacketsOut - m_lastPacketsOut) / time;
                m_lastBytesIn    = Statistics.BytesIn;
                m_lastBytesOut   = Statistics.BytesOut;
                m_lastPacketsIn  = Statistics.PacketsIn;
                m_lastPacketsOut = Statistics.PacketsOut;

                // Get threadpool info
                int iocpCurrent, iocpMin, iocpMax;
                int poolCurrent, poolMin, poolMax;
                ThreadPool.GetAvailableThreads(out poolCurrent, out iocpCurrent);
                ThreadPool.GetMinThreads(out poolMin, out iocpMin);
                ThreadPool.GetMaxThreads(out poolMax, out iocpMax);

                int globalHandlers = GameEventMgr.NumGlobalHandlers;
                int objectHandlers = GameEventMgr.NumObjectHandlers;

                if (log.IsInfoEnabled)
                {
                    StringBuilder stats = new StringBuilder(256)
                                          .Append("-stats- Mem=").Append(GC.GetTotalMemory(false) / 1024 / 1024).Append("MB")
                                          .Append("  Clients=").Append(GameServer.Instance.ClientCount)
                                          .Append("  Down=").Append(inRate / 1024).Append("kb/s (").Append(Statistics.BytesIn / 1024 / 1024).Append("MB)")
                                          .Append("  Up=").Append(outRate / 1024).Append("kb/s (").Append(Statistics.BytesOut / 1024 / 1024).Append("MB)")
                                          .Append("  In=").Append(inPckRate).Append("pck/s (").Append(Statistics.PacketsIn / 1000).Append("K)")
                                          .Append("  Out=").Append(outPckRate).Append("pck/s (").Append(Statistics.PacketsOut / 1000).Append("K)")
                                          .AppendFormat("  Pool={0}/{1}({2})", poolCurrent, poolMax, poolMin)
                                          .AppendFormat("  IOCP={0}/{1}({2})", iocpCurrent, iocpMax, iocpMin)
                                          .AppendFormat("  GH/OH={0}/{1}", globalHandlers, objectHandlers);

                    lock (m_timerStatsByMgr.SyncRoot)
                    {
                        foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers())
                        {
                            TimerStats ts = (TimerStats)m_timerStatsByMgr[mgr];
                            if (ts == null)
                            {
                                ts = new TimerStats();
                                m_timerStatsByMgr.Add(mgr, ts);
                            }
                            long curInvoked = mgr.InvokedCount;
                            long invoked    = curInvoked - ts.InvokedCount;
                            stats.Append("  ").Append(mgr.Name).Append('=').Append(invoked / time).Append("t/s (")
                            .Append(mgr.ActiveTimers).Append(')');
                            ts.InvokedCount = curInvoked;
                        }
                    }

                    if (m_systemCpuUsedCounter != null)
                    {
                        stats.Append("  CPU=").Append(m_systemCpuUsedCounter.NextValue().ToString("0.0")).Append('%');
                    }
                    if (m_processCpuUsedCounter != null)
                    {
                        stats.Append("  DOL=").Append(m_processCpuUsedCounter.NextValue().ToString("0.0")).Append('%');
                    }
                    if (m_memoryPages != null)
                    {
                        stats.Append("  pg/s=").Append(m_memoryPages.NextValue().ToString("0.0"));
                    }
                    if (m_physycalDisk != null)
                    {
                        stats.Append("  dsk/s=").Append(m_physycalDisk.NextValue().ToString("0.0"));
                    }

                    log.Info(stats);
                }

                if (log.IsFatalEnabled)
                {
                    lock (m_timerStatsByMgr.SyncRoot)
                    {
                        foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers())
                        {
                            TimerStats ts = (TimerStats)m_timerStatsByMgr[mgr];
                            if (ts == null)
                            {
                                continue;
                            }

                            long curTick = mgr.CurrentTime;
                            if (ts.Time == curTick)
                            {
                                log.FatalFormat("{0} stopped ticking; timer stacktrace:\n{1}\n", mgr.Name, mgr.GetFormattedStackTrace());
                                log.FatalFormat("NPC update stacktrace:\n{0}\n", WorldMgr.GetFormattedWorldUpdateStackTrace());
                                log.FatalFormat("Relocate() stacktrace:\n{0}\n", WorldMgr.GetFormattedRelocateRegionsStackTrace());
                                log.FatalFormat("Packethandlers stacktraces:\n{0}\n", PacketProcessor.GetConnectionThreadpoolStacks());
                            }

                            ts.Time = curTick;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("stats Log callback", e);
            }
            finally
            {
                lock (typeof(StatPrint))
                {
                    if (m_timer != null)
                    {
                        m_timer.Change(ServerProperties.Properties.STATPRINT_FREQUENCY, 0);
                    }
                }
            }
        }