I'm trying to capture AIX real-time information like CPU, memory, IO load with a C# console application because I would like to show that information in a third part custom dashboard. After running the command topas, I need to capture periodically the whole following text:
I tried to capture it with the following code that I have found out in some forum:
using Renci.SshNet;
using System;
using System.IO;
using System.Threading;
namespace SSH_check_commands
{
public class MyAsyncInfo
{
public MyAsyncInfo(Byte[] array, ShellStream stream)
{
ByteArray = array;
Stream = stream;
}
public Byte[] ByteArray { get; set; }
public ShellStream Stream { get; set; }
}
class Program
{
private static ShellStream stream;
private static SshClient client;
private static byte[] _data = new byte[2048];
static void Main(string[] args)
{
client = new SshClient("host", "user", "password");
client.Connect();
stream = client.CreateShellStream(@"xterm", 80, 24, 800, 600, 1024);
stream.DataReceived += StartAsyncRead;
stream.Write("bash\n");
Thread.Sleep(5000);
stream.Write("topas -i 10\n");
Console.ReadLine();
}
private static void StartAsyncRead(object sender, EventArgs e)
{
try
{
stream.BeginRead(_data, 0, _data.Length, OnReadCompletion, new MyAsyncInfo(_data, stream));
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private static void OnReadCompletion(IAsyncResult ar)
{
try
{
var mai = (MyAsyncInfo)ar.AsyncState;
int datalen = mai.Stream.EndRead(ar);
string line = client.ConnectionInfo.Encoding.GetString(mai.ByteArray, 0, datalen);
Console.Write(line);
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
public static string SendCommand(string cmd, ShellStream sh)
{
StreamReader reader = null;
try
{
reader = new StreamReader(sh);
StreamWriter writer = new StreamWriter(sh);
writer.AutoFlush = true;
writer.WriteLine(cmd);
while (sh.Length == 0)
{
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
Console.WriteLine("exception: " + ex.ToString());
}
return reader.ReadToEnd();
}
}
}
But I can't parse the result because it's not structured:
Could you please help me?
Workaround:
I have changed the approach to the problem. I could not catch whole text with ssh streaming because I receive only changed chars. Hence periodically I run the following ssh command to save nmon content in a file (called hostname_YYMMDD_H24_mm.nmon):
nmon -f -c 1
After with the cat command I can read the file, extract the content, transform it and load it in my dashboard.
The results are structured. Those are ANSI escape codes. You can parse those, the same way your SSH terminal client parses those to display the nice output.
But that's a huge task. See SSH.NET based colored terminal emulator.
Though I'd say that trying to parse an output of a command that is intended for a human use is a bad idea, in the first place. For sure there's another way to retrieve the same information in a format that's easier to parse. But that's a question for another site (for example Super User).
If you just want to strip the ANSI escape codes, you can use a regular expression, as shown in How to remove ^[, and all of the escape sequences in a file using linux shell scripting: