示例#1
0
        public static bool HasScreenAccess()
        {
            string screenName  = "ServerNodeTest_" + Guid.NewGuid().ToString();
            string shellScript = @"-c ""pid=$(screen -S " + screenName + @" -dm sh; screen -ls | awk '/\." + screenName + @"\t/ { print($1) }'); echo $pid;""";

            string[] output = SH.Shell(Program.WorkingDirectory, shellScript);

            foreach (string line in output)
            {
                if (line.Contains(screenName))
                {
                    Log.Verbose("Test Screen Name Captured");

                    string spid = line.Split('.').FirstOrDefault();

                    int pid = Convert.ToInt32(spid);

                    try
                    {
                        Process.GetProcessById(pid).Kill();

                        CleanUpScreens();

                        return(true);
                    }
                    catch (Exception)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#2
0
        public static bool IsPidstatAvailable()
        {
            string[] output = SH.Shell(Program.WorkingDirectory, @"-c pidstat", null, null);

            if (output.Any(x => x.Contains("not found")))
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        // TODO Linux Add Firewall Rule
        internal static bool AddFirewallRule(Server server)
        {
            string[] output1 = SH.Shell(Program.WorkingDirectory, $"-c \"iptables -A INPUT -p udp --dport {server.Port} -j ACCEPT\"");

            if (output1.Count() > 0 && output1.FirstOrDefault().Contains("Permission denied."))
            {
                return(false);
            }

            string[] output2 = SH.Shell(Program.WorkingDirectory, $"-c \"iptables -A INPUT -p tcp --dport {server.Port} -j ACCEPT\"");

            if (output2.Count() > 0 && output2.FirstOrDefault().Contains("Permission denied."))
            {
                return(false);
            }

            return(true);
        }
        public static IEnumerable <int> ProcessTree(int processId)
        {
            string[] pstree    = SH.Shell(Program.WorkingDirectory, @"-c ""pstree " + processId + @" -p""", null, null);
            string   firstLine = pstree.FirstOrDefault();

            string tmpPID = "";

            foreach (char ch in firstLine)
            {
                if (Utility.StringExtension.IsRealDigitOnly(ch))
                {
                    tmpPID += ch;
                }
                else
                {
                    if (!string.IsNullOrEmpty(tmpPID) && tmpPID != "0" && tmpPID.IsDigitsOnly())
                    {
                        yield return(Convert.ToInt32(tmpPID));

                        tmpPID = "";
                    }
                }
            }
        }
        /// <summary>
        /// Begin monitoring the system usage of a process, by id
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="tokenSource"></param>
        /// <param name="tick"></param>
        public override void BeginMonitoring(Server server)
        {
            Task.Run(async() => {
                if (!IsInitialised)
                {
                    Log.Warning("Attempted to begin monitoring a process, but it never initialised!");
                    return;
                }

                Log.Informational($"Began Monitoring Process {this.ProcessId}.");

                try
                {
                    // We need to get the real pid, we currently have the screen pids...
                    IEnumerable <int> pids = Pstree.ProcessTree(ProcessId).SkipLast(1);

                    string[] pidstat_headers = null;

                    while (!this.Token.IsCancellationRequested)
                    {
                        await Task.Delay(this.Tickrate);

                        Token.ThrowIfCancellationRequested();

                        try
                        {
                            // refresh the pids we're watcing, child process can pop up and close at any time
                            pids = Pstree.ProcessTree(ProcessId).SkipLast(1);

                            // get cpu stats, memory stats & disk stats
                            string[] pidstat_values = SH.Shell(Program.WorkingDirectory, @"-c ""pidstat -urdh -p " + string.Join(',', pids) + @"""", null, null).Skip(1).ToArray();

                            if (pidstat_values.Length <= 2)
                            {
                                // we have headers... but no longer have any data to parse.

                                // Linux 4.19.104 - microsoft - standard(LAPTOP - ADAM)         06 / 04 / 2020      _x86_64_(8 CPU)
                                // #      Time   UID       PID    %usr %system  %guest    %CPU   CPU  minflt/s  majflt/s     VSZ     RSS   %MEM   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
                                return;
                            }

                            // headers should only need to be handled once...
                            // #      Time   UID       PID    %usr %system  %guest    %CPU   CPU  minflt/s  majflt/s     VSZ     RSS   %MEM   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

                            if (pidstat_headers == null)
                            {
                                string header_row = pidstat_values[0];
                                // remove stupid #
                                header_row = header_row.Replace("#", "");

                                pidstat_headers = header_row.Split(" ", StringSplitOptions.RemoveEmptyEntries);
                            }

                            double UsageCPU   = 0;
                            double UsageMem   = 0;
                            double UsageDiskW = 0;
                            double UsageDiskR = 0;

                            // data rows.. skipping the headers..
                            foreach (string row in pidstat_values.Skip(1))
                            {
                                string[] cols = row.Split(' ', StringSplitOptions.RemoveEmptyEntries);

                                UsageCPU   += Convert.ToDouble(cols[Array.IndexOf(pidstat_headers, "%CPU")]);
                                UsageMem   += Convert.ToDouble(cols[Array.IndexOf(pidstat_headers, "RSS")]);
                                UsageDiskW += Convert.ToDouble(cols[Array.IndexOf(pidstat_headers, "kB_wr/s")]);
                                UsageDiskR += Convert.ToDouble(cols[Array.IndexOf(pidstat_headers, "kB_rd/s")]);
                            }

                            int padding = PreAPIHelper.Apps.Values.Max(x => x.ShortName.Length);

                            Log.Verbose($"Server {server.ID:00} ({server.App.ShortName.PadLeft(padding)}) Performance - CPU: {UsageCPU:000.00}%" +
                                        $"     Mem: {ServerNode.Utility.ByteMeasurements.KiloBytesToMB(UsageMem):00000.00}MB" +
                                        $"     Disk Write: {ServerNode.Utility.ByteMeasurements.KiloBytesToMB(UsageDiskW):000.00}MB/s" +
                                        $"     Disk Read: {ServerNode.Utility.ByteMeasurements.KiloBytesToMB(UsageDiskR):000.00}MB/s");
                        }
                        catch (NullReferenceException)
                        {
                            Log.Warning("Looks like our server stopped, the performance monitor just broke out.");
                            if (Token.CanBeCanceled)
                            {
                                TokenSource.Cancel();
                            }
                            return;
                        }
                    }
                }
                catch (OperationCanceledException) { }
                catch (Exception ex)
                {
                    Log.Error(ex);
                    throw;
                }
            });
        }
示例#6
0
 public static void CleanUpScreens()
 {
     SH.Shell(Program.WorkingDirectory, @"-c ""screen -wipe;""");
 }