From 076c44b37066b59037d976a82d83590cd3adf86f Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Thu, 26 Mar 2020 10:47:22 +0000
Subject: [PATCH] feature-cmd_stat

---
 dap_chain_node_cli.c     | 64 +++++++++++++++++++++-------------------
 dap_chain_node_cli_cmd.c | 54 ++++++++++++++++++++++++++++++++-
 dap_chain_node_cli_cmd.h |  5 +++-
 3 files changed, 91 insertions(+), 32 deletions(-)

diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c
index 194b0e1fdd..a26e3aca16 100755
--- a/dap_chain_node_cli.c
+++ b/dap_chain_node_cli.c
@@ -1,6 +1,6 @@
 /*
  * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * Dmitriy A. Gerasimov <gerasimov.dmitriy@demlabs.net>
  * Alexander Lysikov <alexander.lysikov@demlabs.net>
  * DeM Labs Inc.   https://demlabs.net
  * Kelvin Project https://github.com/kelvinblockchain
@@ -570,9 +570,9 @@ static void *thread_pipe_client_func( void *args )
 
     log_it( L_INFO, "close connection pipe = %X", hPipe );
 
-    FlushFileBuffers( hPipe ); 
-    DisconnectNamedPipe( hPipe ); 
-    CloseHandle( hPipe ); 
+    FlushFileBuffers( hPipe );
+    DisconnectNamedPipe( hPipe );
+    CloseHandle( hPipe );
 
     return NULL;
 }
@@ -583,44 +583,44 @@ static void *thread_pipe_client_func( void *args )
  */
 static void* thread_pipe_func( void *args )
 {
-   BOOL   fConnected = FALSE; 
+   BOOL   fConnected = FALSE;
    pthread_t threadId;
-   HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 
-   static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe"; 
+   HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
+   static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe";
 
-   for (;;) 
-   { 
+   for (;;)
+   {
 ///      printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename );
 
-      hPipe = CreateNamedPipe( 
-          cPipeName,                // pipe name 
-          PIPE_ACCESS_DUPLEX,       // read/write access 
-          PIPE_TYPE_MESSAGE |       // message type pipe 
-          PIPE_READMODE_MESSAGE |   // message-read mode 
-          PIPE_WAIT,                // blocking mode 
-          PIPE_UNLIMITED_INSTANCES, // max. instances  
-          4096,                     // output buffer size 
-          4096,                     // input buffer size 
-          0,                        // client time-out 
-          NULL );                   // default security attribute 
+      hPipe = CreateNamedPipe(
+          cPipeName,                // pipe name
+          PIPE_ACCESS_DUPLEX,       // read/write access
+          PIPE_TYPE_MESSAGE |       // message type pipe
+          PIPE_READMODE_MESSAGE |   // message-read mode
+          PIPE_WAIT,                // blocking mode
+          PIPE_UNLIMITED_INSTANCES, // max. instances
+          4096,                     // output buffer size
+          4096,                     // input buffer size
+          0,                        // client time-out
+          NULL );                   // default security attribute
 
       if ( hPipe == INVALID_HANDLE_VALUE ) {
           log_it( L_ERROR, "CreateNamedPipe failed, GLE = %d.\n", GetLastError() );
           return NULL;
       }
-  
-      fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED ); 
- 
+
+      fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED );
+
       if ( fConnected )
-      { 
-        log_it( L_INFO, "Client %X connected, creating a processing thread.\n", hPipe ); 
+      {
+        log_it( L_INFO, "Client %X connected, creating a processing thread.\n", hPipe );
 
         pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe );
         pthread_detach( threadId );
-      } 
-      else 
+      }
+      else
          CloseHandle( hPipe );
-    } 
+    }
 
     return NULL;
 }
@@ -864,6 +864,10 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
     dap_chain_node_cli_cmd_item_create ("print_log", com_print_log, "Print log info",
                 "print_log [ts_after <timestamp >] [limit <line numbers>]\n" );
 
+    // Statisticss
+    dap_chain_node_cli_cmd_item_create("stats", com_stats, "Print statistics",
+                "stats cpu");
+
     // Exit
     dap_chain_node_cli_cmd_item_create ("exit", com_exit, "Stop application and exit",
                 "exit\n" );
@@ -931,8 +935,8 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
         const char *l_listen_addr_str = dap_config_get_item_str(g_config, "conserver", "listen_address");
 
         log_it( L_INFO, "Console interace on addr %s port %u ", l_listen_addr_str, l_listen_port );
- 
-        server_addr.sin_family = AF_INET; 
+
+        server_addr.sin_family = AF_INET;
         inet_pton( AF_INET, l_listen_addr_str, &server_addr.sin_addr );
         //server.sin_addr.s_addr = htonl( INADDR_ANY );
         server_addr.sin_port = htons( (uint16_t)l_listen_port );
diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index 6b6b4f5d82..c63b7d439a 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -1,6 +1,6 @@
 /*
  * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * Dmitriy A. Gerasimov <gerasimov.dmitriy@demlabs.net>
  * Alexander Lysikov <alexander.lysikov@demlabs.net>
  * DeM Labs Inc.   https://demlabs.net
  * Kelvin Project https://github.com/kelvinblockchain
@@ -3051,6 +3051,58 @@ int com_tx_history(int argc, char ** argv, char **str_reply)
     return 0;
 }
 
+/**
+ * stats command
+ */
+int com_stats(int argc, char ** argv, char **str_reply)
+{
+    enum {
+        CMD_NONE, CMD_STATS_CPU
+    };
+    int arg_index = 1;
+    int cmd_num = CMD_NONE;
+    // find  add parameter ('cpu')
+    if (dap_chain_node_cli_find_option_val(argv, arg_index, min(argc, arg_index + 1), "cpu", NULL)) {
+        cmd_num = CMD_STATS_CPU;
+    }
+    switch (cmd_num) {
+    case CMD_NONE:
+    default:
+        dap_chain_node_cli_set_reply_text(str_reply, "format of command: stats cpu");
+        return -1;
+    case CMD_STATS_CPU:
+#if (defined DAP_OS_UNIX) || (defined __WIN32)
+    {
+        dap_cpu_monitor_init();
+        usleep(500000);
+        char *str_reply_prev = dap_strdup_printf("");
+        char *str_delimiter;
+        dap_cpu_stats_t s_cpu_stats = dap_cpu_get_stats();
+        for (int n_cpu_num = 0; n_cpu_num < s_cpu_stats.cpu_cores_count; n_cpu_num++) {
+            if ((n_cpu_num % 4 == 0) && (n_cpu_num != 0)) {
+                str_delimiter = dap_strdup_printf("\n");
+            } else if (n_cpu_num == s_cpu_stats.cpu_cores_count - 1) {
+                str_delimiter = dap_strdup_printf("");
+            } else {
+                str_delimiter = dap_strdup_printf(" ");
+            }
+            *str_reply = dap_strdup_printf("%sCPU-%d: %f%%%s", str_reply_prev, n_cpu_num, s_cpu_stats.cpus[n_cpu_num].load, str_delimiter);
+            DAP_DELETE(str_reply_prev);
+            DAP_DELETE(str_delimiter);
+            str_reply_prev = *str_reply;
+        }
+        *str_reply = dap_strdup_printf("%s\nTotal: %f%%", str_reply_prev, s_cpu_stats.cpu_summary.load);
+        DAP_DELETE(str_reply_prev);
+        break;
+    }
+#else
+        dap_chain_node_cli_set_reply_text(str_reply, "only Linux or Windows environment supported");
+        return -1;
+#endif // DAP_OS_UNIX
+    }
+    return 0;
+}
+
 int com_exit(int argc, char ** argv, char **str_reply)
 {
     exit(0);
diff --git a/dap_chain_node_cli_cmd.h b/dap_chain_node_cli_cmd.h
index 7d7a42bac4..8f8aa35ffa 100644
--- a/dap_chain_node_cli_cmd.h
+++ b/dap_chain_node_cli_cmd.h
@@ -1,6 +1,6 @@
 /*
  * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * Dmitriy A. Gerasimov <gerasimov.dmitriy@demlabs.net>
  * Alexander Lysikov <alexander.lysikov@demlabs.net>
  * DeM Labs Inc.   https://demlabs.net
  * Kelvin Project https://github.com/kelvinblockchain
@@ -126,6 +126,9 @@ int com_tx_history(int argc, char ** argv, char **str_reply);
 // Print log info
 int com_print_log(int argc, char ** argv, char **str_reply);
 
+// Print statistics
+int com_stats(int argc, char ** argv, char **str_reply);
+
 int com_exit(int argc, char ** argv, char **str_reply);
 
 // vpn_client command
-- 
GitLab