示例#1
0
        public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var statusCollection = base.CollectServerStatus(nodeStatus);

            if (!m_AppDomainMonitoringSupported)
            {
                return(statusCollection);
            }

            if (statusCollection != null && m_HostDomain != null)
            {
                if (m_Process.TotalProcessorTime.TotalMilliseconds > 0)
                {
                    var value = m_HostDomain.MonitoringTotalProcessorTime.TotalMilliseconds * 100 / m_Process.TotalProcessorTime.TotalMilliseconds;
                    statusCollection[StatusInfoKeys.CpuUsage] = value;
                }

                if (AppDomain.MonitoringSurvivedProcessMemorySize > 0)
                {
                    var value = (double)m_HostDomain.MonitoringSurvivedMemorySize * 100 / (double)AppDomain.MonitoringSurvivedProcessMemorySize;
                    statusCollection[StatusInfoKeys.MemoryUsage] = (double)value;
                }
            }

            return(statusCollection);
        }
        public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
        {
            var state = (app as IsolationApp).AssemblyUpdateState;

            // not in running state
            if (state == null)
            {
                return(false);
            }

            if (state.LastUpdatedTime > state.CurrentAssemblyTime)
            {
                // check to see if there is any latest update
                // if yes, deplay much longer time
                state.TryCheckUpdate();
                return(IsDeplayOverdue(state.LastUpdatedTime));
            }

            // next check time has not reached yet
            if (state.LastCheckTime.AddMinutes(m_CheckInterval) > DateTime.Now)
            {
                return(false);
            }

            if (!state.TryCheckUpdate())
            {
                return(false);
            }

            return(IsDeplayOverdue(state.LastUpdatedTime));
        }
示例#3
0
        public void Collect(StatusInfoCollection statusCollection)
        {
            if (m_CollectThreadPoolInfo)
            {
                int availableWorkingThreads, availableCompletionPortThreads;
                ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

                int maxWorkingThreads;
                int maxCompletionPortThreads;
                ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

                statusCollection[StatusInfoKeys.AvailableWorkingThreads]        = availableWorkingThreads;
                statusCollection[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                statusCollection[StatusInfoKeys.MaxCompletionPortThreads]       = maxCompletionPortThreads;
                statusCollection[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
            }

            var retry = false;

            while (true)
            {
                try
                {
                    for (var i = 0; i < m_CounterDefinitions.Length; i++)
                    {
                        var counterInfo = m_CounterDefinitions[i];
                        var counter     = m_Counters[i];
                        statusCollection[counterInfo.StatusInfoKey] = counterInfo.Read(counter.NextValue());
                    }

                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                    {
                        throw e;
                    }

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || NRackEnv.IsMono)
                    {
                        throw e;
                    }

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(m_Process);

                    if (string.IsNullOrEmpty(newInstanceName))
                    {
                        break;
                    }

                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }
        }
示例#4
0
        public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var status = base.CollectServerStatus(nodeStatus);

            status.Tag = m_ServerTag;
            return(status);
        }
        public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
        {
            var state = (app as IsolationApp).AssemblyUpdateState;

            // not in running state
            if (state == null)
                return false;

            if (state.LastUpdatedTime > state.CurrentAssemblyTime)
            {
                // check to see if there is any latest update
                // if yes, deplay much longer time
                state.TryCheckUpdate();
                return IsDeplayOverdue(state.LastUpdatedTime);
            }

            // next check time has not reached yet
            if (state.LastCheckTime.AddMinutes(m_CheckInterval) > DateTime.Now)
                return false;

            if (!state.TryCheckUpdate())
                return false;

            return IsDeplayOverdue(state.LastUpdatedTime);
        }
示例#6
0
文件: STOP.cs 项目: SagaFav/server-1
        /// <summary>
        /// Executes the async json command.
        /// </summary>
        /// <param name="s">The session.</param>
        /// <param name="token">The token.</param>
        /// <param name="commandInfo">The command info.</param>
        protected override void ExecuteAsyncJsonCommand(Session s, string token, string commandInfo)
        {
            if (!s.IsAuthenticated)
            {
                s.Close();

                return;
            }

            string InstanceName = commandInfo;

            IWorkItem Server = s.AppServer.GetServerByName(InstanceName);

            if (Server == null)
            {
                SendJsonMessage(s, token, new CommandResult {
                    Result = false, Message = string.Format("The server instance \"{0}\" doesn't exist", commandInfo)
                });

                return;
            }

            Server.Stop();

            NodeStatus           NodeStatus = s.AppServer.CurrentNodeStatus;
            StatusInfoCollection Instance   = NodeStatus.InstancesStatus.FirstOrDefault(i => i.Name.Equals(InstanceName));

            Instance[StatusInfoKeys.IsRunning] = false;

            SendJsonMessage(s, token, new CommandResult {
                Result = true, NodeStatus = NodeStatus
            });
        }
示例#7
0
        public override bool Setup(IBootstrap bootstrap, IServerConfig config)
        {
            if (!base.Setup(bootstrap, config))
            {
                return(false);
            }

            var metadata = GetMetadata() as ExternalProcessAppServerMetadata;

            var appFile = metadata.AppFile;

            if (string.IsNullOrEmpty(appFile))
            {
                OnExceptionThrown(new ArgumentNullException("appFile"));
                return(false);
            }

            var workDir = AppWorkingDir;

            if (!string.IsNullOrEmpty(metadata.AppDir))
            {
                appFile = Path.Combine(metadata.AppDir, appFile);
            }

            if (!Path.IsPathRooted(appFile))
            {
                appFile = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, appFile));
            }

            if (!File.Exists(appFile))
            {
                OnExceptionThrown(new FileNotFoundException("The app file was not found.", appFile));
                return(false);
            }

            workDir = Path.GetDirectoryName(appFile);

            m_ExternalAppDir = workDir;

            var args = metadata.AppArgs;

            var startInfo = new ProcessStartInfo(appFile, args);

            startInfo.WorkingDirectory      = workDir;
            startInfo.CreateNoWindow        = true;
            startInfo.WindowStyle           = ProcessWindowStyle.Hidden;
            startInfo.UseShellExecute       = false;
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardInput = true;

            m_StartInfo = startInfo;

            m_ExitCommand = config.Options.Get("exitCommand");

            m_Status = new StatusInfoCollection {
                Name = config.Name
            };

            return(true);
        }
示例#8
0
        void RunRecycleTriggers(StatusInfoCollection status)
        {
            var triggers = RecycleTriggers;

            if (triggers == null || !triggers.Any())
            {
                return;
            }

            foreach (var trigger in triggers)
            {
                var toBeRecycle = false;

                try
                {
                    toBeRecycle = trigger.NeedBeRecycled(this, status) && CanBeRecycled();
                }
                catch (Exception e)
                {
                    OnExceptionThrown(e);
                    continue;
                }

                if (toBeRecycle)
                {
                    Logger.InfoFormat("The app server {0} will be recycled because of the trigger {1}", this.Name, trigger.Name);

                    Task.Factory.StartNew(Restart)
                    .ContinueWith(t => OnExceptionThrown(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

                    break;
                }
            }
        }
示例#9
0
        public void Collect(StatusInfoCollection statusCollection)
        {
            int availableWorkingThreads, availableCompletionPortThreads;

            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;

            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            var retry = false;

            while (true)
            {
                try
                {
                    statusCollection[StatusInfoKeys.AvailableWorkingThreads]        = availableWorkingThreads;
                    statusCollection[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxCompletionPortThreads]       = maxCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
                    if (isWindows || Platform.IsMono)
                    {
                        statusCollection[StatusInfoKeys.TotalThreadCount] = (int)m_ThreadCountPC.NextValue();
                        statusCollection[StatusInfoKeys.CpuUsage]         = m_CpuUsagePC.NextValue() / m_CpuCores;
                        statusCollection[StatusInfoKeys.MemoryUsage]      = (long)m_WorkingSetPC.NextValue();
                    }

                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                    {
                        throw e;
                    }

                    //Only re-get performance counter for .NET/Windows
                    if (!isWindows || Platform.IsMono)
                    {
                        throw e;
                    }

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(m_Process);

                    if (string.IsNullOrEmpty(newInstanceName))
                    {
                        break;
                    }

                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }
        }
示例#10
0
        public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
        {
            var memoryUsage = status[StatusInfoKeys.MemoryUsage];

            if (memoryUsage == null)
                return false;

            return (long)memoryUsage >= m_MaxMemoryUsage;
        }
示例#11
0
        public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var status = base.CollectServerStatus(nodeStatus);
            status.Tag = m_ServerTag;

            if(m_PerformanceCounterHelper != null)
                m_PerformanceCounterHelper.Collect(status);

            return status;
        }
示例#12
0
        public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
        {
            var memoryUsage = status[StatusInfoKeys.MemoryUsage];

            if (memoryUsage == null)
            {
                return(false);
            }

            return((long)memoryUsage >= m_MaxMemoryUsage);
        }
        public void Collect(StatusInfoCollection statusCollection)
        {
            if(m_CollectThreadPoolInfo)
            {
                int availableWorkingThreads, availableCompletionPortThreads;
                ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

                int maxWorkingThreads;
                int maxCompletionPortThreads;
                ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

                statusCollection[StatusInfoKeys.AvailableWorkingThreads] = availableWorkingThreads;
                statusCollection[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                statusCollection[StatusInfoKeys.MaxCompletionPortThreads] = maxCompletionPortThreads;
                statusCollection[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
            }

            var retry = false;

            while (true)
            {
                try
                {
                    for (var i = 0; i < m_CounterDefinitions.Length; i++)
                    {
                        var counterInfo = m_CounterDefinitions[i];
                        var counter = m_Counters[i];
                        statusCollection[counterInfo.StatusInfoKey] = counterInfo.Read(counter.NextValue());
                    }

                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                        throw e;

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || NRackEnv.IsMono)
                        throw e;

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(m_Process);

                    if (string.IsNullOrEmpty(newInstanceName))
                        break;

                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }
        }
示例#14
0
        public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var status = base.CollectServerStatus(nodeStatus);

            status.Tag = m_ServerTag;

            if (m_PerformanceCounterHelper != null)
            {
                m_PerformanceCounterHelper.Collect(status);
            }

            return(status);
        }
示例#15
0
        public virtual StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var appServer = AppServer;

            if (appServer == null)
            {
                var stoppedStatus = GetStoppedStatus();
                stoppedStatus.CollectedTime = DateTime.Now;
                return(stoppedStatus);
            }

            var currentStatus = appServer.CollectServerStatus(nodeStatus);

            m_PrevStatus = currentStatus;
            return(currentStatus);
        }
        public void Collect(StatusInfoCollection statusCollection)
        {
            int availableWorkingThreads, availableCompletionPortThreads;
            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;
            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            var retry = false;

            while (true)
            {
                try
                {
                    statusCollection[StatusInfoKeys.AvailableWorkingThreads] = availableWorkingThreads;
                    statusCollection[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxCompletionPortThreads] = maxCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
                    statusCollection[StatusInfoKeys.TotalThreadCount] = (int)m_ThreadCountPC.NextValue();
                    statusCollection[StatusInfoKeys.CpuUsage] = m_CpuUsagePC.NextValue() / m_CpuCores;
                    statusCollection[StatusInfoKeys.MemoryUsage] = (long)m_WorkingSetPC.NextValue();

                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                        throw e;

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || Platform.IsMono)
                        throw e;

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(m_Process);

                    if (string.IsNullOrEmpty(newInstanceName))
                        break;

                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }
        }
示例#17
0
        private StatusInfoCollection GetStoppedStatus()
        {
            if (m_StoppedStatus == null)
            {
                m_StoppedStatus      = new StatusInfoCollection();
                m_StoppedStatus.Name = Name;
                m_StoppedStatus.Tag  = Name;
                m_StoppedStatus[StatusInfoKeys.IsRunning]           = false;
                m_StoppedStatus[StatusInfoKeys.MaxConnectionNumber] = ServerConfig.MaxConnectionNumber;

                if (m_PrevStatus != null)
                {
                    m_StoppedStatus[StatusInfoKeys.Listeners] = m_PrevStatus[StatusInfoKeys.Listeners];
                }
            }

            return(m_StoppedStatus);
        }
示例#18
0
        public virtual bool Setup(IBootstrap bootstrap, IServerConfig config)
        {
            Bootstrap = bootstrap;

            var loggerProvider = bootstrap as ILoggerProvider;

            if (loggerProvider != null)
            {
                Logger = loggerProvider.Logger;
            }

            State  = ServerState.Initializing;
            Config = config;
            Name   = config.Name;
            State  = ServerState.NotStarted;

            AppWorkingDir = GetAppWorkingDir(Name);

            if (!Directory.Exists(AppWorkingDir))
            {
                Directory.CreateDirectory(AppWorkingDir);
            }

            var appConfigFilePath = GetAppConfigFile();

            // use the application's own config file if it has
            //AppRoot\AppName\App.config
            if (!string.IsNullOrEmpty(appConfigFilePath))
            {
                StartupConfigFile = appConfigFilePath;
            }

            m_NotStartedStatus = new Lazy <StatusInfoCollection>(() =>
            {
                var status = new StatusInfoCollection(m_Metadata.Name);
                status[StatusInfoKeys.IsRunning] = false;
                return(status);
            });

            return(true);
        }
        public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var statusCollection = base.CollectServerStatus(nodeStatus);

            if (!m_AppDomainMonitoringSupported)
                return statusCollection;

            if (statusCollection != null && m_HostDomain != null)
            {
                if (m_Process.TotalProcessorTime.TotalMilliseconds > 0)
                {
                    var value = m_HostDomain.MonitoringTotalProcessorTime.TotalMilliseconds * 100 / m_Process.TotalProcessorTime.TotalMilliseconds;
                    statusCollection[StatusInfoKeys.CpuUsage] = value;
                }

                if (AppDomain.MonitoringSurvivedProcessMemorySize > 0)
                {
                    var value = (double)m_HostDomain.MonitoringSurvivedMemorySize * 100 / (double)AppDomain.MonitoringSurvivedProcessMemorySize;
                    statusCollection[StatusInfoKeys.MemoryUsage] = (double)value;
                }
            }

            return statusCollection;
        }
示例#20
0
        public override bool Setup(IBootstrap bootstrap, IServerConfig config)
        {
            if (!base.Setup(bootstrap, config))
                return false;

            var metadata = GetMetadata() as ExternalProcessAppServerMetadata;

            var appFile = metadata.AppFile;

            if(string.IsNullOrEmpty(appFile))
            {
                OnExceptionThrown(new ArgumentNullException("appFile"));
                return false;
            }

            var workDir = AppWorkingDir;

            if (!string.IsNullOrEmpty(metadata.AppDir))
                appFile = Path.Combine(metadata.AppDir, appFile);

            if(!Path.IsPathRooted(appFile))
            {
                appFile = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, appFile));
            }

            if (!File.Exists(appFile))
            {
                OnExceptionThrown(new FileNotFoundException("The app file was not found.", appFile));
                return false;
            }

            workDir = Path.GetDirectoryName(appFile);

            m_ExternalAppDir = workDir;

            var args = metadata.AppArgs;

            var startInfo = new ProcessStartInfo(appFile, args);
            startInfo.WorkingDirectory = workDir;
            startInfo.CreateNoWindow = true;
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardInput = true;

            m_StartInfo = startInfo;

            m_ExitCommand = config.Options.Get("exitCommand");

            m_Status = new StatusInfoCollection { Name = config.Name };

            return true;
        }
示例#21
0
 protected override void UpdateServerStatus(StatusInfoCollection serverStatus)
 {
     base.UpdateServerStatus(serverStatus);
 }
示例#22
0
        protected override void OnServerStatusCollected(StatusInfoCollection bootstrapStatus, StatusInfoCollection serverStatus)
        {
            base.OnServerStatusCollected(bootstrapStatus, serverStatus);

            NetService.Ping(base.GetAllSessions().GroupBy(l => l.Rid).Count());
        }
示例#23
0
 /// <summary>
 /// Called when [status collected].
 /// </summary>
 /// <param name="status">The app status.</param>
 protected virtual void OnStatusCollected(StatusInfoCollection status)
 {
 }
示例#24
0
        private void OnPerformanceTimerCallback(object state)
        {
            var nodeStatus = new NodeStatus();

            StatusInfoCollection bootstrapStatus = new StatusInfoCollection();

            m_Helper.Collect(bootstrapStatus);

            nodeStatus.BootstrapStatus = bootstrapStatus;

            var instancesStatus = new List <StatusInfoCollection>(m_AppServers.Length);

            var perfBuilder = new StringBuilder();

            perfBuilder.AppendLine("---------------------------------------------------");
            perfBuilder.AppendLine(string.Format("CPU Usage: {0:0.00}%, Physical Memory Usage: {1:N}, Total Thread Count: {2}", bootstrapStatus[StatusInfoKeys.CpuUsage], bootstrapStatus[StatusInfoKeys.MemoryUsage], bootstrapStatus[StatusInfoKeys.TotalThreadCount]));
            perfBuilder.AppendLine(string.Format("AvailableWorkingThreads: {0}, AvailableCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads], bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads]));
            perfBuilder.AppendLine(string.Format("MaxWorkingThreads: {0}, MaxCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.MaxWorkingThreads], bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads]));

            for (var i = 0; i < m_AppServers.Length; i++)
            {
                var s = m_AppServers[i];

                var metadata = m_ServerStatusMetadataSource[i + 1].Value;

                if (metadata == null)
                {
                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", s.Name));
                    perfBuilder.AppendLine(string.Format("{0}: {1}", "State", s.State));
                }
                else
                {
                    var serverStatus = s.CollectServerStatus(bootstrapStatus);

                    instancesStatus.Add(serverStatus);

                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", serverStatus.Tag));

                    for (var j = 0; j < metadata.Length; j++)
                    {
                        var statusInfoAtt = metadata[j];

                        if (!statusInfoAtt.OutputInPerfLog)
                        {
                            continue;
                        }

                        var statusValue = serverStatus[statusInfoAtt.Key];

                        if (statusValue == null)
                        {
                            continue;
                        }

                        perfBuilder.AppendLine(
                            string.Format("{0}: {1}", statusInfoAtt.Name,
                                          string.IsNullOrEmpty(statusInfoAtt.Format) ? statusValue : string.Format(statusInfoAtt.Format, statusValue)));
                    }
                }
            }

            m_PerfLog.Info(perfBuilder.ToString());

            nodeStatus.InstancesStatus = instancesStatus.ToArray();

            if (OnStatusUpdate != null)
            {
                OnStatusUpdate(nodeStatus);
            }

            if (m_ServerManager != null && m_ServerManager.State == ServerState.Running)
            {
                m_ServerManager.TransferSystemMessage("ServerStatusCollected", nodeStatus);
            }
        }
 protected override void UpdateServerStatus(StatusInfoCollection serverStatus)
 {
     Logger.InfoFormat("UpdateServerStatus() serverStatus:'{0}'", serverStatus.ToString());
     base.UpdateServerStatus(serverStatus);
 }
示例#26
0
        void RunRecycleTriggers(StatusInfoCollection status)
        {
            var triggers = RecycleTriggers;

            if (triggers == null || !triggers.Any())
                return;

            foreach (var trigger in triggers)
            {
                var toBeRecycle = false;

                try
                {
                    toBeRecycle = trigger.NeedBeRecycled(this, status) && CanBeRecycled();
                }
                catch (Exception e)
                {
                    OnExceptionThrown(e);
                    continue;
                }

                if (toBeRecycle)
                {
                    Logger.InfoFormat("The app server {0} will be recycled because of the trigger {1}", this.Name, trigger.Name);

                    Task.Factory.StartNew(Restart)
                        .ContinueWith(t => OnExceptionThrown(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

                    break;
                }
            }
        }
示例#27
0
 public override StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
 {
     var status = base.CollectServerStatus(nodeStatus);
     status.Tag = m_ServerTag;
     return status;
 }
        private void OnPerformanceTimerCallback(object state)
        {
            var nodeStatus = new NodeStatus();

            StatusInfoCollection bootstrapStatus = new StatusInfoCollection();
            m_Helper.Collect(bootstrapStatus);

            nodeStatus.BootstrapStatus = bootstrapStatus;

            var instancesStatus = new List<StatusInfoCollection>(m_AppServers.Length);

            var perfBuilder = new StringBuilder();

            perfBuilder.AppendLine("---------------------------------------------------");
            perfBuilder.AppendLine(string.Format("CPU Usage: {0:0.00}%, Physical Memory Usage: {1:N}, Total Thread Count: {2}", bootstrapStatus[StatusInfoKeys.CpuUsage], bootstrapStatus[StatusInfoKeys.MemoryUsage], bootstrapStatus[StatusInfoKeys.TotalThreadCount]));
            perfBuilder.AppendLine(string.Format("AvailableWorkingThreads: {0}, AvailableCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads], bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads]));
            perfBuilder.AppendLine(string.Format("MaxWorkingThreads: {0}, MaxCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.MaxWorkingThreads], bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads]));

            for (var i = 0; i < m_AppServers.Length; i++)
            {
                var s = m_AppServers[i];

                var metadata = m_ServerStatusMetadataSource[i + 1].Value;

                if (metadata == null)
                {
                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", s.Name));
                    perfBuilder.AppendLine(string.Format("{0}: {1}", "State", s.State));
                }
                else
                {
                    var serverStatus = s.CollectServerStatus(bootstrapStatus);

                    instancesStatus.Add(serverStatus);

                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", serverStatus.Tag));

                    for (var j = 0; j < metadata.Length; j++)
                    {
                        var statusInfoAtt = metadata[j];

                        if (!statusInfoAtt.OutputInPerfLog)
                            continue;

                        var statusValue = serverStatus[statusInfoAtt.Key];

                        if (statusValue == null)
                            continue;

                        perfBuilder.AppendLine(
                            string.Format("{0}: {1}", statusInfoAtt.Name,
                            string.IsNullOrEmpty(statusInfoAtt.Format) ? statusValue : string.Format(statusInfoAtt.Format, statusValue)));
                    }
                }
            }

            m_PerfLog.Info(perfBuilder.ToString());

            nodeStatus.InstancesStatus = instancesStatus.ToArray();

            if (OnStatusUpdate != null) OnStatusUpdate(nodeStatus);

            if (m_ServerManager != null && m_ServerManager.State == ServerState.Running)
            {
                m_ServerManager.TransferSystemMessage("ServerStatusCollected", nodeStatus);
            }
        }
 protected override void OnServerStatusCollected(StatusInfoCollection bootstrapStatus, StatusInfoCollection serverStatus)
 {
     Logger.InfoFormat("OnServerStatusCollected() bootstrapStatus:'{0}', serverStatus:'{1}'", bootstrapStatus.ToString(), serverStatus.ToString());
     base.OnServerStatusCollected(bootstrapStatus, serverStatus);
 }
示例#30
0
 public StatusInfoCollection CollectServerStatus(StatusInfoCollection bootstrapStatus)
 {
     throw new NotSupportedException();
 }
示例#31
0
        StatusInfoCollection IManagedAppBase.CollectStatus()
        {
            var status = m_AppStatus;

            if (status == null)
            {
                status = new StatusInfoCollection();
                status.Name = Name;
                status.Tag = Name;
                status.StartedTime = StartedTime;
                m_AppStatus = status;
            }

            UpdateStatus(status);
            Task.Factory.StartNew(() => OnStatusCollected(status)).ContinueWith(t =>
                {
                    Logger.LogAggregateException("Exception happend in OnStatusCollected.", t.Exception);
                }, TaskContinuationOptions.OnlyOnFaulted);
            return status;
        }
示例#32
0
        void RunRecycleTriggers(StatusInfoCollection status)
        {
            var triggers = RecycleTriggers;

            if (triggers == null || !triggers.Any())
                return;

            foreach (var trigger in triggers)
            {
                var toBeRecycle = false;

                try
                {
                    toBeRecycle = trigger.NeedBeRecycled(this, status) && CanBeRecycled();
                }
                catch (Exception e)
                {
                    OnExceptionThrown(e);
                    continue;
                }

                if (toBeRecycle)
                {
                    Task.Factory.StartNew(Restart)
                        .ContinueWith(t => OnExceptionThrown(t.Exception), TaskContinuationOptions.OnlyOnFaulted);
                }
            }
        }
示例#33
0
        public virtual bool Setup(IBootstrap bootstrap, IServerConfig config)
        {
            Bootstrap = bootstrap;

            var loggerProvider = bootstrap as ILoggerProvider;

            if (loggerProvider != null)
                Logger = loggerProvider.Logger;

            State = ServerState.Initializing;
            Config = config;
            Name = config.Name;            
            State = ServerState.NotStarted;

            AppWorkingDir = config.Options.Get("appWorkingDir") ?? GetAppWorkingDir(Name);

            if (!Directory.Exists(AppWorkingDir))
                Directory.CreateDirectory(AppWorkingDir);

            var appConfigFilePath = GetAppConfigFile();

            // use the application's own config file if it has
            //AppRoot\AppName\App.config
            if (!string.IsNullOrEmpty(appConfigFilePath))
                StartupConfigFile = appConfigFilePath;

            m_NotStartedStatus = new Lazy<StatusInfoCollection>(() =>
                {
                    var status = new StatusInfoCollection(m_Metadata.Name);
                    status[StatusInfoKeys.IsRunning] = false;
                    return status;
                });

            return true;
        }
示例#34
0
        private void OnPerformanceTimerCallback(object state)
        {
            var nodeStatus = new NodeStatus();

            int availableWorkingThreads, availableCompletionPortThreads;

            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;

            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            StatusInfoCollection bootstrapStatus = null;

            var retry = false;

            while (true)
            {
                try
                {
                    bootstrapStatus = new StatusInfoCollection();

                    bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads]        = availableWorkingThreads;
                    bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads]       = maxCompletionPortThreads;
                    bootstrapStatus[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
                    bootstrapStatus[StatusInfoKeys.TotalThreadCount]  = (int)m_ThreadCountPC.NextValue();
                    bootstrapStatus[StatusInfoKeys.CpuUsage]          = m_CpuUsagePC.NextValue() / m_CpuCores;
                    bootstrapStatus[StatusInfoKeys.WorkingSet]        = (long)m_WorkingSetPC.NextValue();

                    nodeStatus.BootstrapStatus = bootstrapStatus;
                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                    {
                        throw e;
                    }

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || Platform.IsMono)
                    {
                        throw e;
                    }

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(Process.GetCurrentProcess());
                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }

            var instancesStatus = new List <StatusInfoCollection>(m_AppServers.Length);

            var perfBuilder = new StringBuilder();

            perfBuilder.AppendLine("---------------------------------------------------");
            perfBuilder.AppendLine(string.Format("CPU Usage: {0:0.00}%, Physical Memory Usage: {1:N}, Total Thread Count: {2}", bootstrapStatus[StatusInfoKeys.CpuUsage], bootstrapStatus[StatusInfoKeys.WorkingSet], bootstrapStatus[StatusInfoKeys.TotalThreadCount]));
            perfBuilder.AppendLine(string.Format("AvailableWorkingThreads: {0}, AvailableCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads], bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads]));
            perfBuilder.AppendLine(string.Format("MaxWorkingThreads: {0}, MaxCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.MaxWorkingThreads], bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads]));

            for (var i = 0; i < m_AppServers.Length; i++)
            {
                var s = m_AppServers[i];

                var metadata = m_ServerStatusMetadataSource[i + 1].Value;

                if (metadata == null)
                {
                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", s.Name));
                    perfBuilder.AppendLine(string.Format("{0}: {1}", "IsRunning", s.State == ServerState.Running));
                }
                else
                {
                    var serverStatus = s.CollectServerStatus(bootstrapStatus);

                    instancesStatus.Add(serverStatus);

                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", serverStatus.Tag));

                    for (var j = 0; j < metadata.Length; j++)
                    {
                        var statusInfoAtt = metadata[j];

                        if (!statusInfoAtt.OutputInPerfLog)
                        {
                            continue;
                        }

                        var statusValue = serverStatus[statusInfoAtt.Key];

                        if (statusValue == null)
                        {
                            continue;
                        }

                        perfBuilder.AppendLine(
                            string.Format("{0}: {1}", statusInfoAtt.Name,
                                          string.IsNullOrEmpty(statusInfoAtt.Format) ? statusValue : string.Format(statusInfoAtt.Format, statusValue)));
                    }
                }
            }

            m_PerfLog.Info(perfBuilder.ToString());

            nodeStatus.InstancesStatus = instancesStatus.ToArray();

            if (m_ServerManager != null && m_ServerManager.State == ServerState.Running)
            {
                m_ServerManager.TransferSystemMessage("ServerStatusCollected", nodeStatus);
            }
        }
示例#35
0
 StatusInfoCollection IStatusInfoSource.CollectServerStatus(StatusInfoCollection nodeStatus)
 {
     return(m_AppServer.CollectServerStatus(nodeStatus));
 }
示例#36
0
 public AppServerStatus(AppServerMetadata metadata, StatusInfoCollection dataCollection)
 {
     Metadata = metadata;
     DataCollection = dataCollection;
 }
示例#37
0
        private void OnPerformanceTimerCallback(object state)
        {
            var nodeStatus = new NodeStatus();

            int availableWorkingThreads, availableCompletionPortThreads;
            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;
            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            StatusInfoCollection bootstrapStatus = null;

            var retry = false;

            while(true)
            {
                try
                {
                    bootstrapStatus = new StatusInfoCollection();

                    bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads] = availableWorkingThreads;
                    bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads] = maxCompletionPortThreads;
                    bootstrapStatus[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
                    bootstrapStatus[StatusInfoKeys.TotalThreadCount] = (int)m_ThreadCountPC.NextValue();
                    bootstrapStatus[StatusInfoKeys.CpuUsage] = m_CpuUsagePC.NextValue() / m_CpuCores;
                    bootstrapStatus[StatusInfoKeys.WorkingSet] = (long)m_WorkingSetPC.NextValue();

                    nodeStatus.BootstrapStatus = bootstrapStatus;
                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                        throw e;

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || Platform.IsMono)
                        throw e;

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(Process.GetCurrentProcess());
                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }

            var instancesStatus = new List<StatusInfoCollection>(m_AppServers.Length);

            var perfBuilder = new StringBuilder();

            perfBuilder.AppendLine("---------------------------------------------------");
            perfBuilder.AppendLine(string.Format("CPU Usage: {0:0.00}%, Physical Memory Usage: {1:N}, Total Thread Count: {2}", bootstrapStatus[StatusInfoKeys.CpuUsage], bootstrapStatus[StatusInfoKeys.WorkingSet], bootstrapStatus[StatusInfoKeys.TotalThreadCount]));
            perfBuilder.AppendLine(string.Format("AvailableWorkingThreads: {0}, AvailableCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.AvailableWorkingThreads], bootstrapStatus[StatusInfoKeys.AvailableCompletionPortThreads]));
            perfBuilder.AppendLine(string.Format("MaxWorkingThreads: {0}, MaxCompletionPortThreads: {1}", bootstrapStatus[StatusInfoKeys.MaxWorkingThreads], bootstrapStatus[StatusInfoKeys.MaxCompletionPortThreads]));

            for (var i = 0; i < m_AppServers.Length; i++)
            {
                var s = m_AppServers[i];

                var metadata = m_ServerStatusMetadatas[i];

                if (s is IsolationAppServer)
                {
                    var newMetadata = s.GetServerStatusMetadata();

                    if (newMetadata != metadata)
                    {
                        m_ServerStatusMetadatas[i] = newMetadata;
                        metadata = newMetadata;
                    }
                }

                if (metadata == null)
                {
                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", s.Name));
                    perfBuilder.AppendLine(string.Format("{0}: {1}", "IsRunning", s.State == ServerState.Running));
                }
                else
                {
                    var serverStatus = s.CollectServerStatus(bootstrapStatus);

                    instancesStatus.Add(serverStatus);

                    perfBuilder.AppendLine(string.Format("{0} ----------------------------------", serverStatus.Tag));

                    for (var j = 0; j < metadata.Length; j++)
                    {
                        var statusInfoAtt = metadata[j];

                        if (!statusInfoAtt.OutputInPerfLog)
                            continue;

                        var statusValue = serverStatus[statusInfoAtt.Key];

                        if (statusValue == null)
                            continue;

                        perfBuilder.AppendLine(
                            string.Format("{0}: {1}", statusInfoAtt.Name,
                            string.IsNullOrEmpty(statusInfoAtt.Format) ? statusValue : string.Format(statusInfoAtt.Format, statusValue)));
                    }
                }
            }

            m_PerfLog.Info(perfBuilder.ToString());

            try
            {
                nodeStatus.Save(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "status.bin"));
            }
            catch (Exception e)
            {
                m_PerfLog.Error(e);
            }
        }
        public void Collect(StatusInfoCollection statusCollection)
        {
            int availableWorkingThreads, availableCompletionPortThreads;

            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;

            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            var retry = false;

            while (true)
            {
                try
                {
                    statusCollection[StatusInfoKeys.AvailableWorkingThreads]        = availableWorkingThreads;
                    statusCollection[StatusInfoKeys.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxCompletionPortThreads]       = maxCompletionPortThreads;
                    statusCollection[StatusInfoKeys.MaxWorkingThreads] = maxWorkingThreads;
#if !NETSTANDARD2_0
                    statusCollection[StatusInfoKeys.TotalThreadCount] = (int)m_ThreadCountPC.NextValue();
                    statusCollection[StatusInfoKeys.CpuUsage]         = m_CpuUsagePC.NextValue() / m_CpuCores;
                    statusCollection[StatusInfoKeys.MemoryUsage]      = (long)m_WorkingSetPC.NextValue();
#else
                    var proc = Process.GetCurrentProcess();
                    statusCollection[StatusInfoKeys.TotalThreadCount] = proc.Threads.Count;
                    statusCollection[StatusInfoKeys.CpuUsage]         = proc.TotalProcessorTime.TotalMilliseconds / 1000;
                    statusCollection[StatusInfoKeys.MemoryUsage]      = proc.WorkingSet64 / 1024;
#endif

                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                    {
                        throw e;
                    }

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || Platform.IsMono)
                    {
                        throw e;
                    }

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(m_Process);

                    if (string.IsNullOrEmpty(newInstanceName))
                    {
                        break;
                    }

                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }
        }
示例#39
0
 protected virtual void UpdateStatus(StatusInfoCollection status)
 {
     status[StatusInfoKeys.IsRunning] = (State == ServerState.Running);
 }
示例#40
0
 public StatusInfoCollection CollectServerStatus(StatusInfoCollection bootstrapStatus)
 {
     throw new NotSupportedException();
 }
示例#41
0
        public virtual StatusInfoCollection CollectServerStatus(StatusInfoCollection nodeStatus)
        {
            var appServer = AppServer;

            if (appServer == null)
            {
                var stoppedStatus = GetStoppedStatus();
                stoppedStatus.CollectedTime = DateTime.Now;
                return stoppedStatus;
            }

            var currentStatus = appServer.CollectServerStatus(nodeStatus);
            m_PrevStatus = currentStatus;
            return currentStatus;
        }
示例#42
0
        private StatusInfoCollection GetStoppedStatus()
        {
            if (m_StoppedStatus == null)
            {
                m_StoppedStatus = new StatusInfoCollection();
                m_StoppedStatus.Name = Name;
                m_StoppedStatus.Tag = Name;
                m_StoppedStatus[StatusInfoKeys.IsRunning] = false;
                m_StoppedStatus[StatusInfoKeys.MaxConnectionNumber] = ServerConfig.MaxConnectionNumber;

                if (m_PrevStatus != null)
                {
                    m_StoppedStatus[StatusInfoKeys.Listeners] = m_PrevStatus[StatusInfoKeys.Listeners];
                }
            }

            return m_StoppedStatus;
        }
示例#43
0
 protected override void OnServerStatusCollected(StatusInfoCollection bootstrapStatus, StatusInfoCollection serverStatus)
 {
     base.OnServerStatusCollected(bootstrapStatus, serverStatus);
 }
示例#44
0
 StatusInfoCollection IStatusInfoSource.CollectServerStatus(StatusInfoCollection nodeStatus)
 {
     return m_AppServer.CollectServerStatus(nodeStatus);
 }
示例#45
0
        private void OnPerformanceTimerCallback(object state)
        {
            int availableWorkingThreads, availableCompletionPortThreads;

            ThreadPool.GetAvailableThreads(out availableWorkingThreads, out availableCompletionPortThreads);

            int maxWorkingThreads;
            int maxCompletionPortThreads;

            ThreadPool.GetMaxThreads(out maxWorkingThreads, out maxCompletionPortThreads);

            StatusInfoCollection globalPerfData = null;

            var retry = false;

            while (true)
            {
                try
                {
                    globalPerfData = new StatusInfoCollection();

                    globalPerfData[ProcessStatusInfoMetadata.AvailableWorkingThreads]        = availableWorkingThreads;
                    globalPerfData[ProcessStatusInfoMetadata.AvailableCompletionPortThreads] = availableCompletionPortThreads;
                    globalPerfData[ProcessStatusInfoMetadata.MaxCompletionPortThreads]       = maxCompletionPortThreads;
                    globalPerfData[ProcessStatusInfoMetadata.MaxWorkingThreads] = maxWorkingThreads;
                    globalPerfData[ProcessStatusInfoMetadata.TotalThreadCount]  = (int)m_ThreadCountPC.NextValue();
                    globalPerfData[ProcessStatusInfoMetadata.CpuUsage]          = m_CpuUsagePC.NextValue() / m_CpuCores;
                    globalPerfData[ProcessStatusInfoMetadata.WorkingSet]        = (long)m_WorkingSetPC.NextValue();
                    break;
                }
                catch (InvalidOperationException e)
                {
                    //Only re-get performance counter one time
                    if (retry)
                    {
                        throw e;
                    }

                    //Only re-get performance counter for .NET/Windows
                    if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX || Platform.IsMono)
                    {
                        throw e;
                    }

                    //If a same name process exited, this process's performance counters instance name could be changed,
                    //so if the old performance counter cannot be access, get the performance counter's name again
                    var newInstanceName = GetPerformanceCounterInstanceName(Process.GetCurrentProcess());
                    SetupPerformanceCounters(newInstanceName);
                    retry = true;
                }
            }

            var perfBuilder = new StringBuilder();

            perfBuilder.AppendLine("---------------------------------------------------");
            perfBuilder.AppendLine(string.Format("CPU Usage: {0:0.00}%, Physical Memory Usage: {1:N}, Total Thread Count: {2}", globalPerfData[ProcessStatusInfoMetadata.CpuUsage], globalPerfData[ProcessStatusInfoMetadata.WorkingSet], globalPerfData[ProcessStatusInfoMetadata.TotalThreadCount]));
            perfBuilder.AppendLine(string.Format("AvailableWorkingThreads: {0}, AvailableCompletionPortThreads: {1}", globalPerfData[ProcessStatusInfoMetadata.AvailableWorkingThreads], globalPerfData[ProcessStatusInfoMetadata.AvailableCompletionPortThreads]));
            perfBuilder.AppendLine(string.Format("MaxWorkingThreads: {0}, MaxCompletionPortThreads: {1}", globalPerfData[ProcessStatusInfoMetadata.MaxWorkingThreads], globalPerfData[ProcessStatusInfoMetadata.MaxCompletionPortThreads]));

            for (var i = 0; i < m_AppServers.Length; i++)
            {
                var s = m_AppServers[i];

                var serverStatus = s.CollectServerStatus(globalPerfData);
                var metadata     = m_ServerStatusMetadatas[i];

                perfBuilder.AppendLine(string.Format("{0} ----------------------------------", serverStatus.Tag));

                for (var j = 0; j < metadata.Length; j++)
                {
                    var statusInfoAtt = metadata[j];

                    if (!statusInfoAtt.OutputInPerfLog)
                    {
                        continue;
                    }

                    perfBuilder.AppendLine(
                        string.Format("{0}: {1}", statusInfoAtt.Name,
                                      string.IsNullOrEmpty(statusInfoAtt.Format) ? serverStatus[statusInfoAtt.Key] : string.Format(statusInfoAtt.Format, serverStatus[statusInfoAtt.Key])));
                }
            }

            m_PerfLog.Info(perfBuilder.ToString());
        }