Merge "Clean autotest folder"
[nonrtric.git] / test / simulator-group / sim-monitor.js
1 /*
2 #  ============LICENSE_START===============================================
3 #  Copyright (C) 2020 Nordix Foundation. All rights reserved.
4 #  ========================================================================
5 #  Licensed under the Apache License, Version 2.0 (the "License");
6 #  you may not use this file except in compliance with the License.
7 #  You may obtain a copy of the License at
8 #
9 #       http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #  Unless required by applicable law or agreed to in writing, software
12 #  distributed under the License is distributed on an "AS IS" BASIS,
13 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #  See the License for the specific language governing permissions and
15 #  limitations under the License.
16 #  ============LICENSE_END=================================================
17 #
18 */
19
20 // Sim mon server - query the agent and the simulators for counters and other data
21 // Presents a web page on localhost:9999/mon
22
23 var LOCALHOST="http://127.0.0.1:"
24 var MRSTUB_PORT="3905"
25 var AGENT_PORT="8081"
26 var CR_PORT="8090"
27 var http = require('http');
28
29 var express = require('express');
30 var app = express();
31 var fieldSize=32;
32
33
34
35 //I am alive
36 app.get("/",function(req, res){
37         res.send("ok");
38 })
39
40 //Get parameter valuue from other server
41 function getSimCtr(url, index, cb) {
42     var data = '';
43         http.get(url, (resp) => {
44                 // A chunk of data has been recieved.
45                 resp.on('data', (chunk) => {
46                 data += chunk;
47                 });
48
49                 // The whole response has been received.
50                 resp.on('end', () => {
51             var code=resp.statusCode
52             if (code > 199 && code < 300) {
53                 cb(data, index);
54             } else {
55                 cb("not found", index);
56             }
57                 });
58
59         }).on("error", (err) => {
60                 console.log("Error: " + err.message);
61                 cb("no response", index);
62         });
63 };
64
65
66 //Format a comma separated list of data to a html-safe string with fixed fieldsizes
67 function formatDataRow(commaList) {
68         var str = "";
69         var tmp=commaList.split(',');
70     for(var i=0;i<tmp.length;i++) {
71         var data=tmp[i];
72         var len = fieldSize-data.length;
73         while(len>0) {
74             data = data+"&nbsp;";
75             len--;
76         }
77         str=str+data+"&nbsp;&nbsp;&nbsp;";
78      }
79         return str;
80 }
81
82 //Format a comma separated list of ids to a html-safe string with fixed fieldsizes
83 function formatIdRow(commaList) {
84         var str = "";
85         var tmp=commaList.split(',');
86     for(var i=0;i<tmp.length;i++) {
87         tmp[i] = tmp[i].trim();
88         var data="&lt"+tmp[i]+"&gt";
89         var len = fieldSize+4-data.length;
90         while(len>0) {
91             data = data+"&nbsp;";
92             len--;
93         }
94         str=str+data+"&nbsp;&nbsp;&nbsp;";
95     }
96         return str;
97 }
98
99 //Format a list of ids to a html-safe string in compact format
100 function formatIdRowCompact(commaList) {
101     if (commaList == undefined) {
102         commaList= "";
103     }
104         var str = "";
105         var tmp=commaList.split(',');
106     for(var i=0;i<tmp.length;i++) {
107         tmp[i] = tmp[i].trim();
108         var data="&lt"+tmp[i]+"&gt";
109         str=str+data+"&nbsp;";
110     }
111         return str;
112 }
113
114 //Pad a string upto a certain size using a pad string
115 function padding(val, fieldSize, pad) {
116         var s=""+val;
117         for(var i=s.length;i<fieldSize;i++) {
118                 s=s+pad
119         }
120         return s;
121 }
122
123 //Status variables, for parameters values fetched from other simulators
124 var mr1="", mr2="", mr3="", mr4="", mr5="", mr6="";
125
126 //Status variables for agent
127 var ag1=""
128 var ag2=""
129 var ag3=""
130 var ag4=""
131
132 //Status variables for callback receiver
133 var cr1=""
134 var cr2=""
135 var cr3=""
136
137
138 //Container names and ports of the ric simulator
139 var simnames=[]
140 var simports=[]
141
142 //Status variables for each ric simulator
143 var simvar1=[]
144 var simvar2=[]
145 var simvar3=[]
146 var simvar4=[]
147
148 //Counts the number of get request for the html page
149 var getCtr=0
150
151 var refreshInterval=2000
152
153 function fetchAllMetrics() {
154     setTimeout(() => {
155
156         console.log("Fetching all metics data")
157         if (refreshInterval < 20000) {
158             refreshInterval+=100
159         }
160         if (getCtr%3 == 0) {
161             //Extract the port numbers from the running simulators, for every 3 calls
162             const { exec } = require('child_process');
163             exec('docker ps --filter "name=ricsim" --format "{{.Names}} {{.Ports}}" | sed s/0.0.0.0:// | cut -d \'>\' -f1 | sed \'s/[[-]]*$//\'', (err, stdout, stderr) => {
164
165                 var simulators = ""
166                 simulators=`${stdout}`.replace(/(\r\n|\n|\r)/gm," ");
167                 simulators=simulators.trim();
168                 var sims=simulators.split(" ")
169                 simnames=[]
170                 simports=[]
171                 for(i=0;i<sims.length;i=i+2) {
172                     simnames[i/2]=sims[i]
173                     simports[i/2]=sims[i+1]
174                 }
175             });
176         }
177         getCtr=getCtr+1
178
179         //Get metric values from the simulators
180         for(var index=0;index<simnames.length;index++) {
181             getSimCtr(LOCALHOST+simports[index]+"/counter/num_instances", index, function(data, index) {
182                 simvar1[index] = data;
183             });
184             getSimCtr(LOCALHOST+simports[index]+"/counter/num_types", index, function(data,index) {
185                 simvar2[index] = data;
186             });
187             getSimCtr(LOCALHOST+simports[index]+"/policytypes", index, function(data,index) {
188                 data=data.replace(/\[/g,'');
189                 data=data.replace(/\]/g,'');
190                 data=data.replace(/ /g,'');
191                 data=data.replace(/\"/g,'');
192                 simvar3[index] = data;
193             });
194             getSimCtr(LOCALHOST+simports[index]+"/counter/interface", index, function(data,index) {
195                 simvar4[index] = data;
196             });
197         }
198
199         //MR - get metrics values from the MR stub
200         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_submitted", 0, function(data, index) {
201             mr1 = data;
202         });
203         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_fetched", 0, function(data, index) {
204             mr2 = data;
205         });
206         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_requests", 0, function(data, index) {
207             mr3 = data;
208         });
209         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_submitted", 0, function(data, index) {
210             mr4 = data;
211         });
212         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_fetched", 0, function(data, index) {
213             mr5 = data;
214         });
215         getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_responses", 0, function(data, index) {
216             mr6 = data;
217         });
218
219         //CR - get metrics values from the callbackreceiver
220         getSimCtr(LOCALHOST+CR_PORT+"/counter/received_callbacks", 0, function(data, index) {
221             cr1 = data;
222         });
223         getSimCtr(LOCALHOST+CR_PORT+"/counter/fetched_callbacks", 0, function(data, index) {
224             cr2 = data;
225         });
226         getSimCtr(LOCALHOST+CR_PORT+"/counter/current_messages", 0, function(data, index) {
227             cr3 = data;
228         });
229
230         //Agent - get metrics from the agent
231         getSimCtr(LOCALHOST+AGENT_PORT+"/status", 0, function(data, index) {
232             ag1 = data;
233         });
234         getSimCtr(LOCALHOST+AGENT_PORT+"/services", 0, function(data, index) {
235             ag2="";
236             try {
237                 var jd=JSON.parse(data);
238                 for(var key in jd) {
239                     if (ag2.length > 1) {
240                         ag2=ag2+", "
241                     }
242                     ag2=ag2+(jd[key]["serviceName"]).trim()
243                 }
244             }
245             catch (err) {
246                 ag2=data
247             }
248         });
249         getSimCtr(LOCALHOST+AGENT_PORT+"/policy_types", 0, function(data, index) {
250             ag3="";
251             try {
252                 var jd=JSON.parse(data);
253                 for(var key in jd) {
254                     if (ag3.length > 0) {
255                         ag3=ag3+", "
256                     }
257                     ag3=ag3+jd[key].trim()
258                 }
259             }
260             catch (err) {
261                 ag3=""
262             }
263         });
264         getSimCtr(LOCALHOST+AGENT_PORT+"/policy_ids", 0, function(data, index) {
265             ag4=""
266             try {
267                 var jd=JSON.parse(data);
268                 ag4=""+jd.length
269             }
270             catch (err) {
271                 ag4=""
272             }
273         });
274
275
276
277         fetchAllMetrics();
278     }, refreshInterval)
279 }
280
281 fetchAllMetrics();
282
283 setInterval(() => {
284     console.log("Setting interval "+refreshInterval+"ms")
285 }, refreshInterval)
286
287 app.get("/mon",function(req, res){
288
289
290     refreshInterval=2000
291
292   //Build web page
293         var htmlStr = "<!DOCTYPE html>" +
294           "<html>" +
295           "<head>" +
296             "<meta http-equiv=\"refresh\" content=\"2\">"+  //2 sec auto refresh
297             "<title>Policy Agent and simulator monitor</title>"+
298             "</head>" +
299             "<body>" +
300             "<h3>Policy agent</h3>" +
301             "<font face=\"monospace\">" +
302             "Status:..............................." + formatDataRow(ag1) + "<br>" +
303             "Services:............................." + formatIdRowCompact(ag2) + "<br>" +
304             "Types:................................" + formatIdRowCompact(ag3) + "<br>" +
305             "Number of instances:.................." + formatDataRow(ag4) + "<br>" +
306             "</font>" +
307             "<h3>MR Stub interface</h3>" +
308             "<font face=\"monospace\">"+
309             "Submitted requests:............................" + formatDataRow(mr1) + "<br>" +
310             "Fetched requests:.............................." + formatDataRow(mr2) + "<br>" +
311             "Current requests waiting:......................" + formatDataRow(mr3) + "<br>" +
312             "Submitted responses:..........................." + formatDataRow(mr4) + "<br>" +
313             "Fetched responses.............................." + formatDataRow(mr5) + "<br>" +
314             "Current responses waiting......................" + formatDataRow(mr6) + "<br>" +
315             "</font>"+
316             "<h3>Callback receiver</h3>" +
317             "<font face=\"monospace\">" +
318             "Callbacks received:..................." + formatDataRow(cr1) + "<br>" +
319             "Callbacks fetched:...................." + formatDataRow(cr2) + "<br>" +
320             "Number of waiting callback messages:.." + formatDataRow(cr3) + "<br>" +
321             "</font>" +
322             "<h3>Near-RT RIC Simulators</h3>" +
323             "<font face=\"monospace\">"
324
325             htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
326             htmlStr=htmlStr+padding("Types", 10,"&nbsp;")
327             htmlStr=htmlStr+padding("Instances", 10,"&nbsp;")
328             htmlStr=htmlStr+"<br>"+padding("",55,"=")+"<br>"
329
330             for(var simIndex=0;simIndex<simnames.length;simIndex++) {
331                 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
332                 htmlStr=htmlStr+padding(simvar2[simIndex],10,"&nbsp;")
333                 htmlStr=htmlStr+padding(simvar1[simIndex],10,"&nbsp;")
334                 htmlStr=htmlStr+"<br>";
335             }
336
337             htmlStr=htmlStr+"<br>";
338             htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
339             htmlStr=htmlStr+padding("Version", 20,"&nbsp;")
340             htmlStr=htmlStr+padding("Type-IDs", 10,"&nbsp;")+"<br>"
341             htmlStr=htmlStr+padding("",65,"=")+"<br>"
342             for(simIndex=0;simIndex<simnames.length;simIndex++) {
343                 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
344                 htmlStr=htmlStr+padding(simvar4[simIndex],20,"&nbsp;")
345                 htmlStr=htmlStr+padding(formatIdRowCompact(simvar3[simIndex]),10,"&nbsp;")
346                 htmlStr=htmlStr+"<br>";
347             }
348
349             htmlStr=htmlStr+
350            "</body>" +
351           "</html>";
352         res.send(htmlStr);
353 })
354
355 var httpServer = http.createServer(app);
356 var httpPort=9999;
357 httpServer.listen(httpPort);
358 console.log("Simulator monitor listening (http) at "+httpPort);
359 console.log("Open the web page on localhost:9999/mon to view the statistics page.")