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
9 # http://www.apache.org/licenses/LICENSE-2.0
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=================================================
20 // Sim mon server - query the agent and the simulators for counters and other data
21 // Presents a web page on localhost:9999/mon
23 var LOCALHOST="http://127.0.0.1:"
24 var MRSTUB_PORT="3905"
27 var http = require('http');
29 var express = require('express');
36 app.get("/",function(req, res){
40 //Get parameter valuue from other server
41 function getSimCtr(url, index, cb) {
44 console.log("URL: "+ url + " - ")
46 http.get(url, (resp) => {
47 // A chunk of data has been recieved.
48 resp.on('data', (chunk) => {
52 // The whole response has been received.
53 resp.on('end', () => {
54 var code=resp.statusCode
55 if (code > 199 && code < 300) {
58 cb("not found", index);
62 }).on("error", (err) => {
63 console.log("Error: " + err.message);
64 cb("no response", index);
67 cb("no response", index);
72 //Format a comma separated list of data to a html-safe string with fixed fieldsizes
73 function formatDataRow(commaList) {
75 var tmp=commaList.split(',');
76 for(var i=0;i<tmp.length;i++) {
78 var len = fieldSize-data.length;
83 str=str+data+" ";
88 //Format a comma separated list of ids to a html-safe string with fixed fieldsizes
89 function formatIdRow(commaList) {
91 var tmp=commaList.split(',');
92 for(var i=0;i<tmp.length;i++) {
93 tmp[i] = tmp[i].trim();
94 var data="<"+tmp[i]+">";
95 var len = fieldSize+4-data.length;
100 str=str+data+" ";
105 //Format a list of ids to a html-safe string in compact format
106 function formatIdRowCompact(commaList) {
107 if (commaList == undefined) {
111 var tmp=commaList.split(',');
112 for(var i=0;i<tmp.length;i++) {
113 tmp[i] = tmp[i].trim();
114 var data="<"+tmp[i]+">";
115 str=str+data+" ";
120 //Pad a string upto a certain size using a pad string
121 function padding(val, fieldSize, pad) {
123 for(var i=s.length;i<fieldSize;i++) {
129 //Function to check if the previous call has returned, if so return true, if not return false
130 //For preventing multiple calls to slow containers.
131 function checkFunctionFlag(flag) {
132 if (flagstore.hasOwnProperty(flag)) {
133 if (flagstore[flag] == 0) {
136 } else if (flagstore[flag] > 10) {
137 //Reset flag after ten attempts
138 console.log("Force release flag "+flag)
142 //Previous call not returned
143 console.log("Flag not available "+flag)
144 flagstore[flag]=flagstore[flag]+1
152 //Clear flag for parameter
153 function clearFlag(flag) {
157 //Status variables, for parameters values fetched from other simulators
158 var mr1="", mr2="", mr3="", mr4="", mr5="", mr6="";
160 //Status variables for agent
166 //Status variables for callback receiver
172 //Container names and ports of the ric simulator
176 //Status variables for each ric simulator
183 //Counts the number of get request for the html page
186 var refreshInterval=4000
188 function fetchAllMetrics() {
191 console.log("Fetching all metics data")
192 if (refreshInterval < 20000) {
196 //Extract the port numbers from the running simulators, for every 3 calls
197 const { exec } = require('child_process');
198 exec('docker ps --filter "name=ricsim" --format "{{.Names}} {{.Ports}}" | sed s/0.0.0.0:// | cut -d \'>\' -f1 | sed \'s/[[-]]*$//\'', (err, stdout, stderr) => {
201 simulators=`${stdout}`.replace(/(\r\n|\n|\r)/gm," ");
202 simulators=simulators.trim();
203 var sims=simulators.split(" ")
206 for(i=0;i<sims.length;i=i+2) {
207 simnames[i/2]=sims[i]
208 simports[i/2]=sims[i+1]
214 //Get metric values from the simulators
215 for(var index=0;index<simnames.length;index++) {
217 if (checkFunctionFlag("simvar1_"+index)) {
218 getSimCtr(LOCALHOST+simports[index]+"/counter/num_instances", index, function(data, index) {
219 simvar1[index] = data;
220 clearFlag("simvar1_"+index)
223 if (checkFunctionFlag("simvar2_"+index)) {
224 getSimCtr(LOCALHOST+simports[index]+"/counter/num_types", index, function(data,index) {
225 simvar2[index] = data;
226 clearFlag("simvar2_"+index)
229 if (checkFunctionFlag("simvar3_"+index)) {
230 getSimCtr(LOCALHOST+simports[index]+"/policytypes", index, function(data,index) {
231 data=data.replace(/\[/g,'');
232 data=data.replace(/\]/g,'');
233 data=data.replace(/ /g,'');
234 data=data.replace(/\"/g,'');
235 simvar3[index] = data;
236 clearFlag("simvar3_"+index)
239 if (checkFunctionFlag("simvar4_"+index)) {
240 getSimCtr(LOCALHOST+simports[index]+"/counter/interface", index, function(data,index) {
241 simvar4[index] = data;
242 clearFlag("simvar4_"+index)
245 if (checkFunctionFlag("simvar5_"+index)) {
246 getSimCtr(LOCALHOST+simports[index]+"/counter/remote_hosts", index, function(data,index) {
247 simvar5[index] = data;
248 clearFlag("simvar5_"+index)
253 //MR - get metrics values from the MR stub
254 if (checkFunctionFlag("mr1")) {
255 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_submitted", 0, function(data, index) {
260 if (checkFunctionFlag("mr2")) {
261 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/requests_fetched", 0, function(data, index) {
266 if (checkFunctionFlag("mr3")) {
267 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_requests", 0, function(data, index) {
272 if (checkFunctionFlag("mr4")) {
273 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_submitted", 0, function(data, index) {
278 if (checkFunctionFlag("mr5")) {
279 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/responses_fetched", 0, function(data, index) {
284 if (checkFunctionFlag("mr6")) {
285 getSimCtr(LOCALHOST+MRSTUB_PORT+"/counter/current_responses", 0, function(data, index) {
291 //CR - get metrics values from the callbackreceiver
292 if (checkFunctionFlag("cr1")) {
293 getSimCtr(LOCALHOST+CR_PORT+"/counter/received_callbacks", 0, function(data, index) {
298 if (checkFunctionFlag("cr2")) {
299 getSimCtr(LOCALHOST+CR_PORT+"/counter/fetched_callbacks", 0, function(data, index) {
304 if (checkFunctionFlag("cr3")) {
305 getSimCtr(LOCALHOST+CR_PORT+"/counter/current_messages", 0, function(data, index) {
310 //Agent - more get metrics from the agent
311 if (checkFunctionFlag("ag1")) {
312 getSimCtr(LOCALHOST+AGENT_PORT+"/status", 0, function(data, index) {
317 if (checkFunctionFlag("ag2")) {
318 getSimCtr(LOCALHOST+AGENT_PORT+"/services", 0, function(data, index) {
321 var jd=JSON.parse(data);
323 if (ag2.length > 1) {
326 ag2=ag2+(jd[key]["serviceName"]).trim()
335 if (checkFunctionFlag("ag3")) {
336 getSimCtr(LOCALHOST+AGENT_PORT+"/policy_types", 0, function(data, index) {
339 var jd=JSON.parse(data);
341 if (ag3.length > 0) {
344 ag3=ag3+jd[key].trim()
353 if (checkFunctionFlag("ag4")) {
354 getSimCtr(LOCALHOST+AGENT_PORT+"/policy_ids", 0, function(data, index) {
357 var jd=JSON.parse(data);
375 console.log("Setting interval "+refreshInterval+"ms")
378 app.get("/mon",function(req, res){
384 var htmlStr = "<!DOCTYPE html>" +
387 "<meta http-equiv=\"refresh\" content=\"2\">"+ //2 sec auto refresh
388 "<title>Policy Agent and simulator monitor</title>"+
391 "<h3>Policy agent</h3>" +
392 "<font face=\"monospace\">" +
393 "Status:..............................." + formatDataRow(ag1) + "<br>" +
394 "Services:............................." + formatIdRowCompact(ag2) + "<br>" +
395 "Types:................................" + formatIdRowCompact(ag3) + "<br>" +
396 "Number of instances:.................." + formatDataRow(ag4) + "<br>" +
398 "<h3>MR Stub interface</h3>" +
399 "<font face=\"monospace\">"+
400 "Submitted requests:............................" + formatDataRow(mr1) + "<br>" +
401 "Fetched requests:.............................." + formatDataRow(mr2) + "<br>" +
402 "Current requests waiting:......................" + formatDataRow(mr3) + "<br>" +
403 "Submitted responses:..........................." + formatDataRow(mr4) + "<br>" +
404 "Fetched responses.............................." + formatDataRow(mr5) + "<br>" +
405 "Current responses waiting......................" + formatDataRow(mr6) + "<br>" +
407 "<h3>Callback receiver</h3>" +
408 "<font face=\"monospace\">" +
409 "Callbacks received:..................." + formatDataRow(cr1) + "<br>" +
410 "Callbacks fetched:...................." + formatDataRow(cr2) + "<br>" +
411 "Number of waiting callback messages:.." + formatDataRow(cr3) + "<br>" +
413 "<h3>Near-RT RIC Simulators</h3>" +
414 "<font face=\"monospace\">"
416 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35," ")
417 htmlStr=htmlStr+padding("Types", 10," ")
418 htmlStr=htmlStr+padding("Instances", 10," ")+"<br>"
419 htmlStr=htmlStr+padding("",55,"=")+"<br>"
420 for(var simIndex=0;simIndex<simnames.length;simIndex++) {
421 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35," ");
422 htmlStr=htmlStr+padding(simvar2[simIndex],10," ")
423 htmlStr=htmlStr+padding(simvar1[simIndex],10," ")
424 htmlStr=htmlStr+"<br>";
427 htmlStr=htmlStr+"<br>";
428 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35," ")
429 htmlStr=htmlStr+padding("Version", 20," ")
430 htmlStr=htmlStr+padding("Type-IDs", 10," ")+"<br>"
431 htmlStr=htmlStr+padding("",65,"=")+"<br>"
432 for(simIndex=0;simIndex<simnames.length;simIndex++) {
433 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35," ");
434 htmlStr=htmlStr+padding(simvar4[simIndex],20," ")
435 htmlStr=htmlStr+padding(formatIdRowCompact(simvar3[simIndex]),10," ")
436 htmlStr=htmlStr+"<br>";
439 htmlStr=htmlStr+"<br>";
440 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35," ")
441 htmlStr=htmlStr+padding("Remote hosts", 50," ")+"<br>"
442 htmlStr=htmlStr+padding("",90,"=")+"<br>"
443 for(simIndex=0;simIndex<simnames.length;simIndex++) {
444 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35," ");
445 htmlStr=htmlStr+padding(simvar5[simIndex],50," ")
446 htmlStr=htmlStr+"<br>";
455 var httpServer = http.createServer(app);
457 httpServer.listen(httpPort);
458 console.log("Simulator monitor listening (http) at "+httpPort);
459 console.log("Open the web page on localhost:9999/mon to view the statistics page.")