blob: 76739f35eca309e55f90904c3902186a4154c071 [file] [log] [blame]
BjornMagnussonXA80a92002020-03-19 14:31:06 +01001/*
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
23var LOCALHOST="http://127.0.0.1:"
BjornMagnussonXA72667f12020-04-24 09:20:18 +020024var LOCALHOSTSECURE="https://127.0.0.1:"
25//This var may switch between LOCALHOST and LOCALHOSTSECURE
26var SIM_LOCALHOST=LOCALHOST
BjornMagnussonXA80a92002020-03-19 14:31:06 +010027var MRSTUB_PORT="3905"
28var AGENT_PORT="8081"
29var CR_PORT="8090"
30var http = require('http');
BjornMagnussonXA72667f12020-04-24 09:20:18 +020031var https = require('https');
BjornMagnussonXA80a92002020-03-19 14:31:06 +010032
33var express = require('express');
34var app = express();
35var fieldSize=32;
36
37
38
39//I am alive
40app.get("/",function(req, res){
41 res.send("ok");
42})
43
44//Get parameter valuue from other server
BjornMagnussonXA72667f12020-04-24 09:20:18 +020045function getSimCtr(httpx, url, index, cb) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +010046 var data = '';
BjornMagnussonXA72667f12020-04-24 09:20:18 +020047 var http_type=http
48 if (httpx=="https") {
49 http_type=https
50 }
51 console.log("URL: "+ url + " - " + httpx)
52 try {
53 http_type.get(url, (resp) => {
54 // A chunk of data has been recieved.
55 resp.on('data', (chunk) => {
56 data += chunk;
57 });
BjornMagnussonXA80a92002020-03-19 14:31:06 +010058
BjornMagnussonXA72667f12020-04-24 09:20:18 +020059 // The whole response has been received.
60 resp.on('end', () => {
61 var code=resp.statusCode
62 if (code > 199 && code < 300) {
63 cb(data, index);
64 } else {
65 cb("not found", index);
66 }
67 });
BjornMagnussonXA80a92002020-03-19 14:31:06 +010068
BjornMagnussonXA72667f12020-04-24 09:20:18 +020069 }).on("error", (err) => {
70 console.log("Error: " + err.message);
71 cb("no response", index);
72 });
73 } catch(err) {
74 cb("no response", index);
75 }
BjornMagnussonXA80a92002020-03-19 14:31:06 +010076};
77
78
79//Format a comma separated list of data to a html-safe string with fixed fieldsizes
80function formatDataRow(commaList) {
81 var str = "";
82 var tmp=commaList.split(',');
83 for(var i=0;i<tmp.length;i++) {
84 var data=tmp[i];
85 var len = fieldSize-data.length;
86 while(len>0) {
87 data = data+"&nbsp;";
88 len--;
89 }
90 str=str+data+"&nbsp;&nbsp;&nbsp;";
91 }
92 return str;
93}
94
95//Format a comma separated list of ids to a html-safe string with fixed fieldsizes
96function formatIdRow(commaList) {
97 var str = "";
98 var tmp=commaList.split(',');
99 for(var i=0;i<tmp.length;i++) {
100 tmp[i] = tmp[i].trim();
101 var data="&lt"+tmp[i]+"&gt";
102 var len = fieldSize+4-data.length;
103 while(len>0) {
104 data = data+"&nbsp;";
105 len--;
106 }
107 str=str+data+"&nbsp;&nbsp;&nbsp;";
108 }
109 return str;
110}
111
112//Format a list of ids to a html-safe string in compact format
113function formatIdRowCompact(commaList) {
114 if (commaList == undefined) {
115 commaList= "";
116 }
117 var str = "";
118 var tmp=commaList.split(',');
119 for(var i=0;i<tmp.length;i++) {
120 tmp[i] = tmp[i].trim();
121 var data="&lt"+tmp[i]+"&gt";
122 str=str+data+"&nbsp;";
123 }
124 return str;
125}
126
127//Pad a string upto a certain size using a pad string
128function padding(val, fieldSize, pad) {
129 var s=""+val;
130 for(var i=s.length;i<fieldSize;i++) {
131 s=s+pad
132 }
133 return s;
134}
135
136//Status variables, for parameters values fetched from other simulators
137var mr1="", mr2="", mr3="", mr4="", mr5="", mr6="";
138
139//Status variables for agent
140var ag1=""
141var ag2=""
142var ag3=""
143var ag4=""
144
145//Status variables for callback receiver
146var cr1=""
147var cr2=""
148var cr3=""
149
150
151//Container names and ports of the ric simulator
152var simnames=[]
153var simports=[]
154
155//Status variables for each ric simulator
156var simvar1=[]
157var simvar2=[]
158var simvar3=[]
159var simvar4=[]
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200160var simvar5=[]
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100161
162//Counts the number of get request for the html page
163var getCtr=0
164
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200165var refreshInterval=4000
166
167//Ignore self signed cert
168process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
169
170var sim_http_type="http"
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100171
172function fetchAllMetrics() {
173 setTimeout(() => {
174
175 console.log("Fetching all metics data")
176 if (refreshInterval < 20000) {
177 refreshInterval+=100
178 }
179 if (getCtr%3 == 0) {
180 //Extract the port numbers from the running simulators, for every 3 calls
181 const { exec } = require('child_process');
182 exec('docker ps --filter "name=ricsim" --format "{{.Names}} {{.Ports}}" | sed s/0.0.0.0:// | cut -d \'>\' -f1 | sed \'s/[[-]]*$//\'', (err, stdout, stderr) => {
183
184 var simulators = ""
185 simulators=`${stdout}`.replace(/(\r\n|\n|\r)/gm," ");
186 simulators=simulators.trim();
187 var sims=simulators.split(" ")
188 simnames=[]
189 simports=[]
190 for(i=0;i<sims.length;i=i+2) {
191 simnames[i/2]=sims[i]
192 simports[i/2]=sims[i+1]
193 }
194 });
195 }
196 getCtr=getCtr+1
197
198 //Get metric values from the simulators
199 for(var index=0;index<simnames.length;index++) {
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200200 try {
201 if (index == 0) {
202 // Check is simulator are running on http or https - no response assumes http
203 getSimCtr("https",LOCALHOSTSECURE+simports[index]+"/", index, function(data, index) {
204 if (data=="OK") {
205 console.log("Found https simulator - assuming all simulators using https" )
206 sim_http_type="https"
207 SIM_LOCALHOST=LOCALHOSTSECURE
208 } else {
209 console.log("No https simulator found - assuming all simulators using http" )
210 sim_http_type="http"
211 SIM_LOCALHOST=LOCALHOST
212 }
213 });
214
215 }
216 } catch(err) {
217 console.log("No https simulator found - assuming all simulators using http" )
218 sim_http_type="http"
219 SIM_LOCALHOST=LOCALHOST
220 }
221 getSimCtr(sim_http_type, SIM_LOCALHOST+simports[index]+"/counter/num_instances", index, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100222 simvar1[index] = data;
223 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200224 getSimCtr(sim_http_type, SIM_LOCALHOST+simports[index]+"/counter/num_types", index, function(data,index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100225 simvar2[index] = data;
226 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200227 getSimCtr(sim_http_type, SIM_LOCALHOST+simports[index]+"/policytypes", index, function(data,index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100228 data=data.replace(/\[/g,'');
229 data=data.replace(/\]/g,'');
230 data=data.replace(/ /g,'');
231 data=data.replace(/\"/g,'');
232 simvar3[index] = data;
233 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200234 getSimCtr(sim_http_type, SIM_LOCALHOST+simports[index]+"/counter/interface", index, function(data,index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100235 simvar4[index] = data;
236 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200237 getSimCtr(sim_http_type, SIM_LOCALHOST+simports[index]+"/counter/remote_hosts", index, function(data,index) {
238 simvar5[index] = data;
239 });
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100240 }
241
242 //MR - get metrics values from the MR stub
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200243 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/requests_submitted", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100244 mr1 = data;
245 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200246 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/requests_fetched", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100247 mr2 = data;
248 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200249 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/current_requests", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100250 mr3 = data;
251 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200252 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/responses_submitted", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100253 mr4 = data;
254 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200255 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/responses_fetched", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100256 mr5 = data;
257 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200258 getSimCtr("http", LOCALHOST+MRSTUB_PORT+"/counter/current_responses", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100259 mr6 = data;
260 });
261
262 //CR - get metrics values from the callbackreceiver
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200263 getSimCtr("http", LOCALHOST+CR_PORT+"/counter/received_callbacks", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100264 cr1 = data;
265 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200266 getSimCtr("http", LOCALHOST+CR_PORT+"/counter/fetched_callbacks", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100267 cr2 = data;
268 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200269 getSimCtr("http", LOCALHOST+CR_PORT+"/counter/current_messages", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100270 cr3 = data;
271 });
272
273 //Agent - get metrics from the agent
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200274 getSimCtr("http", LOCALHOST+AGENT_PORT+"/status", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100275 ag1 = data;
276 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200277 getSimCtr("http", LOCALHOST+AGENT_PORT+"/services", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100278 ag2="";
279 try {
280 var jd=JSON.parse(data);
281 for(var key in jd) {
282 if (ag2.length > 1) {
283 ag2=ag2+", "
284 }
285 ag2=ag2+(jd[key]["serviceName"]).trim()
286 }
287 }
288 catch (err) {
289 ag2=data
290 }
291 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200292 getSimCtr("http", LOCALHOST+AGENT_PORT+"/policy_types", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100293 ag3="";
294 try {
295 var jd=JSON.parse(data);
296 for(var key in jd) {
297 if (ag3.length > 0) {
298 ag3=ag3+", "
299 }
300 ag3=ag3+jd[key].trim()
301 }
302 }
303 catch (err) {
304 ag3=""
305 }
306 });
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200307 getSimCtr("http", LOCALHOST+AGENT_PORT+"/policy_ids", 0, function(data, index) {
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100308 ag4=""
309 try {
310 var jd=JSON.parse(data);
311 ag4=""+jd.length
312 }
313 catch (err) {
314 ag4=""
315 }
316 });
317
318
319
320 fetchAllMetrics();
321 }, refreshInterval)
322}
323
324fetchAllMetrics();
325
326setInterval(() => {
327 console.log("Setting interval "+refreshInterval+"ms")
328}, refreshInterval)
329
330app.get("/mon",function(req, res){
331
332
333 refreshInterval=2000
334
335 //Build web page
336 var htmlStr = "<!DOCTYPE html>" +
337 "<html>" +
338 "<head>" +
339 "<meta http-equiv=\"refresh\" content=\"2\">"+ //2 sec auto refresh
340 "<title>Policy Agent and simulator monitor</title>"+
341 "</head>" +
342 "<body>" +
343 "<h3>Policy agent</h3>" +
344 "<font face=\"monospace\">" +
345 "Status:..............................." + formatDataRow(ag1) + "<br>" +
346 "Services:............................." + formatIdRowCompact(ag2) + "<br>" +
347 "Types:................................" + formatIdRowCompact(ag3) + "<br>" +
348 "Number of instances:.................." + formatDataRow(ag4) + "<br>" +
349 "</font>" +
350 "<h3>MR Stub interface</h3>" +
351 "<font face=\"monospace\">"+
352 "Submitted requests:............................" + formatDataRow(mr1) + "<br>" +
353 "Fetched requests:.............................." + formatDataRow(mr2) + "<br>" +
354 "Current requests waiting:......................" + formatDataRow(mr3) + "<br>" +
355 "Submitted responses:..........................." + formatDataRow(mr4) + "<br>" +
356 "Fetched responses.............................." + formatDataRow(mr5) + "<br>" +
357 "Current responses waiting......................" + formatDataRow(mr6) + "<br>" +
358 "</font>"+
359 "<h3>Callback receiver</h3>" +
360 "<font face=\"monospace\">" +
361 "Callbacks received:..................." + formatDataRow(cr1) + "<br>" +
362 "Callbacks fetched:...................." + formatDataRow(cr2) + "<br>" +
363 "Number of waiting callback messages:.." + formatDataRow(cr3) + "<br>" +
364 "</font>" +
365 "<h3>Near-RT RIC Simulators</h3>" +
366 "<font face=\"monospace\">"
367
368 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
369 htmlStr=htmlStr+padding("Types", 10,"&nbsp;")
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200370 htmlStr=htmlStr+padding("Instances", 10,"&nbsp;")+"<br>"
371 htmlStr=htmlStr+padding("",55,"=")+"<br>"
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100372 for(var simIndex=0;simIndex<simnames.length;simIndex++) {
373 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
374 htmlStr=htmlStr+padding(simvar2[simIndex],10,"&nbsp;")
375 htmlStr=htmlStr+padding(simvar1[simIndex],10,"&nbsp;")
376 htmlStr=htmlStr+"<br>";
377 }
378
379 htmlStr=htmlStr+"<br>";
380 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
381 htmlStr=htmlStr+padding("Version", 20,"&nbsp;")
382 htmlStr=htmlStr+padding("Type-IDs", 10,"&nbsp;")+"<br>"
383 htmlStr=htmlStr+padding("",65,"=")+"<br>"
384 for(simIndex=0;simIndex<simnames.length;simIndex++) {
385 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
386 htmlStr=htmlStr+padding(simvar4[simIndex],20,"&nbsp;")
387 htmlStr=htmlStr+padding(formatIdRowCompact(simvar3[simIndex]),10,"&nbsp;")
388 htmlStr=htmlStr+"<br>";
389 }
390
BjornMagnussonXA72667f12020-04-24 09:20:18 +0200391 htmlStr=htmlStr+"<br>";
392 htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
393 htmlStr=htmlStr+padding("Remote hosts", 50,"&nbsp;")+"<br>"
394 htmlStr=htmlStr+padding("",90,"=")+"<br>"
395 for(simIndex=0;simIndex<simnames.length;simIndex++) {
396 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
397 htmlStr=htmlStr+padding(simvar5[simIndex],50,"&nbsp;")
398 htmlStr=htmlStr+"<br>";
399 }
400
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100401 htmlStr=htmlStr+
402 "</body>" +
403 "</html>";
404 res.send(htmlStr);
405})
406
407var httpServer = http.createServer(app);
408var httpPort=9999;
409httpServer.listen(httpPort);
410console.log("Simulator monitor listening (http) at "+httpPort);
411console.log("Open the web page on localhost:9999/mon to view the statistics page.")