Grafana란, 시계열 매트릭 데이터를 시각화 하는데 가장 최적화된 대시보드를 제공해주는 오픈소스 툴킷이다.
- ShinChul Bang, FINDA 기술블로그 Apr 23, 2020
Grafana는 실시간 데이터를 가져오기 때문에, 실시간 데이터베이스가 필요했습니다. MySQL이 실시간 데이터베이스가 아니기 때문에 넣는 데이터를 타임스탬프와 해당 값들을 새롭게 데이터베이스에 저장해주었습니다.
MySQL을 real-time database처럼 사용하기 위해서 localhost:3306를 listen하는 간단한 서버를 만들었습니다. seunghwanly/mobius-docker/mobius/ 디렉토리안에 mysql_radar로 만들어두었습니다. 약간의 코드 설명을 하자면 구조는 다음과 같이 이루어져있습니다.
mysql_radar
└───node_modules
│ .env
│ connection.js
│ grafanadb.sql
│ index.js
│ package-lock.json
│ package.json
| parse.js
.env
파일은 새롭게 생성하여, MySQL에 설정하신 비밀번호와 listen할 데이터베이스이름과 포트를 입력해주시면됩니다.
DB_PASSWORD=Password789!
DB_NAME=mobiusdb
DB_PORT=3306
connection.js
는 'grafana'라는 DB(데이터베이스)를 생성하여 해당 데이터베이스를 연결하는 역할을 해줍니다. connectionInfo
안에 정보들을 담아 init()
과 connect()
함수를 만들어 사용하였습니다.
index.js
는 MySQL를 사용하여 두개의 데이터베이스에 접근합니다. 먼저 '@rodrigogs/mysql-events'를 이용하여 레이더에서 수신해온 데이터가 저장되는 mobiusdb를 listen합니다. 그리고 connection.js
에서 설정한 함수와 import한 패키지를 이용하여 listen해서 들어온 data를 grafana 데이터베이스에 저장해줍니다.
const program = async () => {
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: process.env.DB_PASSWORD,
});
const instance = new MySQLEvents(connection, {
startAtEnd: true,
excludedSchemas: {
mysql: true,
},
});
await instance.start();
instance.addTrigger({
name: 'monitoring . . .',
expression: 'mobiusdb.cin',
statement: MySQLEvents.STATEMENTS.ALL,
onEvent: (event) => {
// these are for grafana
var timeStamp = parseInt(event.timestamp);
var msg = event.affectedRows[0].after.con;
var jsonObject = parseRadar(msg.toString());
// pos
var pos = {
x: jsonObject.message.content !== null ? jsonObject.message.content.pos_x : null,
y: jsonObject.message.content !== null ? jsonObject.message.content.pos_y : null,
z: jsonObject.message.content !== null ? jsonObject.message.content.pos_z : null
};
// bpm
var bpm = jsonObject.message.content !== null ? jsonObject.message.content.bpm : null;
// hbr
var hbr = jsonObject.message.content !== null ? jsonObject.message.content.hbr : null;
// energy
var eng = jsonObject.message.content !== null ? jsonObject.message.content.energy : null;
console.log(timeStamp + ' : ' + JSON.stringify(pos), bpm, hbr, eng);
// save to grafana
// pos
var sqlPos = 'INSERT INTO pos (pos_x, pos_y, pos_z, time) VALUES (?, ?, ?, ?)';
var prmPos = [pos.x, pos.y, pos.z, timeStamp];
// bpm
var sqlBpm = 'INSERT INTO bpm (val, time) VALUES (?, ?)';
var prmBpm = [bpm, timeStamp];
// hbr
var sqlHbr = 'INSERT INTO hbr (val, time) VALUES (?, ?)';
var prmHbr = [hbr, timeStamp];
// energy
var sqlEng = 'INSERT INTO energy (val, time) VALUES (?, ?)';
var prmEng = [eng, timeStamp];
grafanaConn.query(sqlPos, prmPos, (e) => e ? console.log(e) : console.log('insert_pos'));
if(bpm !== NaN)
grafanaConn.query(sqlBpm, prmBpm, (e) => e ? console.log(e) : console.log('insert_bpm'));
if(hbr !== NaN)
grafanaConn.query(sqlHbr, prmHbr, (e) => e ? console.log(e) : console.log('insert_hbr'));
if(eng !== NaN)
grafanaConn.query(sqlEng, prmEng, (e) => e ? console.log(e) : console.log('insert_eng'));
},
});
instance.on(MySQLEvents.EVENTS.CONNECTION_ERROR, console.error);
instance.on(MySQLEvents.EVENTS.ZONGJI_ERROR, console.error);
};
addTrigger()
안에서 event
가 발생할 경우, timestamp
와 'con' 컬럼에서 데이터를 가져옵니다. 가져온 데이터를 parse.js
에 있는 함수로 parsing 해주어 결과를 저장한 후, grafana 데이터베이스에 다시 저장해줍니다. raw하게 쿼리문을 이용하였습니다.
여기를 통해서 다운로드를 받으신 후 진행을 하셔도 되고, 도커(docker)가 다운로드된 상태라면 도커(docker)를 사용하는 방법도 있습니다.
링크 모음
Manual Download :
Docker Image :
Grafana 설정이 완료되었다면, 이제 listen할 데이터베이스를 설정해주면 됩니다. 그전에 Grafana에서 listen할 데이터베이스를 새로운 user가 접근할 수 있도록 MySQL 설정을 추가해주면 추가적인 에러가 발생하지 않는다고 합니다. 방법은 다음과 같습니다.
mysql> CREATE USER 'grafanaReader' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.03 sec)
mysql> GRANT SELECT ON mobiusdb.cin TO 'grafanaReader';
Query OK, 0 rows affected (0.00 sec)
위와같이 설정해두면 User Permission 문제가 발생할 일이 없습니다. 😁
그리고 사용할 데이터에 대한 데이터베이스와 테이블을 새롭게 만들었습니다. 우선 읽어올 수 있는 데이터를 이용하여 x,y,z 좌표, bpm, hbr 그리고 energy에 관한 테이블을 만들어 사용하는 예제입니다. 테이블을 총 4개이며, 결과창에는 4개의 대시보드가 출력되게 하였습니다.
앞서 설정한 <MySQL import 와 동일한 방법>으로 grafanadb.sql
파일을 import 해주시면 알맞은 테이블 4개가 생성됩니다.
설정을 마친 후 Grafana를 실행시켜 localhost:3000으로 접속하게되면, 초기 로그인 계정은
ID : admin / PW : admin
으로 로그인이 가능합니다. 로그인을 하게되면 변경해달라는 문구가 나오며 비밀번호를 변경해주세요 !
로그인을 하고, 왼쪽 바에서 톱니바퀴모양(Configuration) ⚙︎을 선택하고 Data Source로 이동합니다.
누르게 되면 'Add data source' 버튼을 눌러 MySQL을 검색해줍니다.
MySQL을 클릭하고 들어가면 안에 입력하는 칸을 모두 채우고
정보 입력
Save&Test 진행
'Save&Test'를 진행해 데이터베이스와 연동이 잘 이루어지는지 확인해봅니다 ! 잘 진행됐다면 Home으로 돌아가서 새로운 Dashboard를 추가해봅시다.😁
Create > Dashboard
MySQL 선택
Add new Panel
원하는 테이블, 컬럼 및 이름 설정
mobius-docker/mobius에서 아래와 같은 스크립트를 실행합니다.
npm run dev
위 스크립트를 실행하면 mosquitto, mobius 그리고 nCube-thyme가 실행됩니다.
위 스크립트가 모두 실행이 완료되면 그 후에, mobius-docker/mobius/mysql_radar에서 아래와 같이 스크립트를 실행해주세요.
npm run dev
위 스크립트를 실행하면 TAS-RADAR와 MySQL-listener가 실행됩니다.
가장 중요한 MySQL server가 실행되고 있는지 제일 먼저 확인해주시고 실행해주시길 바랍니다 !
이로써 하나의 TAS를 이용해서 Mobius Platform과 연동하는 예제를 진행해보았습니다.😁 들어오는 데이터를 가지고 디바이스제어 등 여러가지를 할 수 있습니다.
감사합니다. 😁