Делаем визуальный контроль серверов с помощью PROCESSING

oper2Как я уже писал ранее, я нашел интересную библиотеку JavaScript которая использует элемент CONVAS и сегодня я расскажу как я сделал визуальный контроль серверов с помощью нее.

В общем у нас есть много серверов, которые мы контролируем. Сервера разделены на несколько групп и на каждом сервере много параметров контроля.  Моя задача была вывести эти сервера на экран и сигнализировать о наличии проблем на каком либо сервере.  Так как такой контроль уже был реализован ранее, но в некоторых вещах не устраивал, я решил сделать такое же отображение, но новым инструментом. Отображение представляет себя прямоугольники зеленого цвета объединенные в группы. При наличии каких либо ошибок на сервере он начинает мигать и окрашивается в разный цвет, в зависимости от приоритета ошибки (всего 3 приоритета).

Создаем первую таблицу в которой будут описываться группы серверов

-- Create table
 create table OPER_GROUPS
 (
 G_ID    NUMBER,
 G_NAME  VARCHAR2(1000), -- наименование группы, выводится сверху
 STATUS  NUMBER default 0, -- статус группы - отображать или нет
 GX      NUMBER, -- координата X верхнего левого угла
 GY      NUMBER, -- координата  Y верхнего левого угла
 GWIDTH  NUMBER, -- Ширина прямоугольника группы
 GHEIGHT NUMBER -- высота прямоугольника группы
 )
 tablespace USERS2
 pctfree 10
 initrans 1
 maxtrans 255
 storage
 (
 initial 64K
 minextents 1
 maxextents unlimited
 );

Создаем таблицу в которой будут описываться наши сервера.
-- Create table
 create table OPER_GROUP_RW
 (
 RW_ID   NUMBER not null, --идентификатор сервера
 G_ID    NUMBER default 0 not null, --идентификатор группы серверов
 STATUS  NUMBER default 0,
 ORD     NUMBER default 0, -- порядок вывода
 SX      NUMBER, --координата Х
 SY      NUMBER, -- координата Y
 SWIDTH  NUMBER, -- ширина
 SHEIGHT NUMBER, -- высота
 SNAME   VARCHAR2(30) -- имя (выводится слева от сервера
 )
 tablespace USERS2
 pctfree 10
 initrans 1
 maxtrans 255
 storage
 (
 initial 64K
 minextents 1
 maxextents unlimited
 );
 -- Create/Recreate primary, unique and foreign key constraints
 alter table OPER_GROUP_RW
 add constraint PK_RWG primary key (RW_ID, G_ID)
 using index
 tablespace USERS2
 pctfree 10
 initrans 2
 maxtrans 255
 storage
 (
 initial 64K
 minextents 1
 maxextents unlimited
 );

Далее нам нужно представление, которые выводит все сервера и самый высокий  (в нашем случаее 1 — самый высокий приоритет, 3 — самый низкий, 4 — нет аварий). Ее содержание зависит от источника в котором вы берете ошибки. Главное чтобы он выдавала два поля — RW_ID, как идентификатор сервера и MAX_PRIORITY как самый высокий приоритет.

Ну а далее вот процедура на PL/SQL для вывода нашего графического режима:

procedure oper2 is
 i        number;
 begin

htp.p('<HTML>');
 htp.p('<HEAD>');
 htp.p('<LINK REL=Stylesheet TYPE="text/css" HREF="CSVT_MON.DYN_CSS.show">');
 htp.p('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />');
 htp.p('<META HTTP-EQUIV="REFRESH" CONTENT="10">');
 htp.p('<script src="/js/processing.js"></script>
 <script src="/js/init.js"></script>
 <script type="text/javascript" src="/js/excanvas.js"></script>
 <script type="text/javascript">
 function init(){
 canvas = document.getElementById("canvas1");
 script = document.getElementById("script1").text;
 Processing(canvas, script);
 }
 </script>

');

htp.p('</HEAD>');
 htp.p('
 <script type="application/processing" id="script1">
 void setup()
 {
 size(1000, 800);  // Size should be the first statement
 stroke(0);     // Set stroke color to white
 fontA = loadFont("Arial");
 textFont(fontA);
 textSize(20);
 frameRate(4);
 }

float y = 100;
 int c = 0;
 int normal_color=255;
 int[] priority_colors = new int[4];
 priority_colors[4]=color(0,255,0);
 priority_colors[1]=color(255,0,0);
 priority_colors[2]=color(255,163,15);
 priority_colors[3]=color(255,242,0);
 String[][] servers = new String[100][7];

void draw()
 {
 background(255);   // Set the background to black
 fill(255);
 ');

for i in (select * from oper_groups g where g.status=1 order by g.g_id)   loop
 htp.p('fill(255);
 ');
 htp.p('server_group('''||i.g_name||''','||i.gx||','||i.gy||','||i.gwidth||','||i.gheight||');');
 end loop;

i:=1;
 for j in (select r.*, p.max_priority, g.gx, g.gy
 from v_oper_rwp    p,
 oper_group_rw r,
 oper_groups   g
 where p.rw_id = r.rw_id
 and r.g_id = g.g_id
 and r.sx is not null)   loop
 htp.p(' server('||(j.gx+j.sx)||','||(j.gy+j.sy)||','||j.swidth||','||j.sheight||',0,normal_color,'''||j.sname||''','||j.max_priority||'); ');
 htp.p('
 servers["'||i||'"]["sx"]='||(j.gx+j.sx)||';
 servers["'||i||'"]["sy"]='||(j.gy+j.sy)||';
 servers["'||i||'"]["sw"]='||j.swidth||';
 servers["'||i||'"]["sh"]='||j.sheight||';
 servers["'||i||'"]["spriority"]='||j.max_priority||';
 servers["'||i||'"]["sname"]="'||j.sname||'";
 servers["'||i||'"]["rw_id"]='||j.rw_id||';
 ');
 i:=i+1;
 end loop;

htp.p('

if (c == 0) c=1; else c=0;
 }
 ');

htp.p('
 void server(int x, int y, int swidth, int sheight, int border_color,int fill_color, String sname, int spriority)
 {
 fill(0);
 text(sname,x+swidth+10,y+sheight/2+10);
 stroke(border_color);
 if (spriority != 4 )
 {
 if (c == 0)
 fill(fill_color);
 else
 fill(priority_colors[spriority]);
 }
 else fill(priority_colors[spriority]);
 rect(x,y,swidth,sheight);
 }

void server_group (string sg_name, int sg_x,int sg_y, int sg_width, int sg_height) {
 fill(normal_color);
 rect(sg_x, sg_y, sg_width, sg_height);
 fill(0);
 text(sg_name,sg_x,sg_y-5 );
 }

void mousePressed()
 {
 int sX;
 int sY;
 int eX;
 int eY;

for (int i=1; i<60; i++) {
 sX=int(servers[i]["sx"]);
 sY=int(servers[i]["sy"]);
 eX=sX+int(servers[i]["sw"]);
 eY=sY+int(servers[i]["sh"]);
 //text(servers[i]["sname"]+"/"+sX+"/"+sY,500,100+i*10);
 if (mouseX > sX && mouseX< eX && mouseY > sY && mouseY<eY) {
 text(servers[i]["sname"]+"/"+sX+"/"+sY ,500,500);
 link("http://XXXXXXXXXX?p_id="+servers[i]["rw_id"],"_new");
 }
 }

}
 </script><canvas id="convas1"></canvas>');

htp.p('<BODY rightMargin="0" onload="init();">');

htp.p('</BODY></HTML>');
 exception when others then
 htp.p(sqlerrm());
 end oper2;

Очень красиво все мигает и при нажатии мышкой на сервер — в новом окне открывается нужная страница, которой передается идентификатор сервера, чтобы можно было вывести там информацию по ошибках на данном сервере.

Весь код представлен для СУБД ORACLE и языка PL/SQL

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

CAPTCHA image
*