Fabric์์ ๋ฐ์ํ๋ ํธ๋์ญ์ ๋ค์ ํํฐ๋งํ์ฌ ELK Stack์ ์ ์ฅํด ๋ณด์๋ค.
Elastic Search๋ ๋ฐ์ดํฐ๋ค์ ์ธ๋ฑ์ฑํ์ฌ ๋น ๋ฅธ ๊ฒ์์ ๋์์ค๋ค.
ํฅํ ํธ์๋ฅผ ์ํ ๋จ์ ๋ฐ์ดํฐ ์กฐํ์ ๊ฐ์ ๊ธฐ๋ฅ์ ELK๋ก ๋ฐ๋ก ๋ถ๋ฆฌํ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ํ, Kibana๋ฅผ ํตํด ์ ์ฅ๋ ๋ฐ์ดํฐ๋ค์ ๋ค์ํ ๊ฐ๋๋ก ๋ชจ๋ํฐ๋ง ํ ์ ์๋ค๋ ์ฅ์ ์ ๊ฐ์ง๊ณ ์๋ค.
Fabric Network 1. Block Commit
|
|
V
EventListener 2. Block Log & Filtered Log ์ ์ฅ
|
|
V
Filebeat 3. Logํ์ผ์ ๋ณ๊ฒฝ์ ํ์ธํ๊ณ Logstash์๊ฒ ์ ๋ฌ
|
|
V
Logstash 4. Filebeat์ Output์ ํํฐ๋ง ํ์ฌ Elaticsearch์๊ฒ ์ ๋ฌ
|
|
V
Elasticsearch 5. ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ
|
|
V
Kibana 6. ์ ์ฅ๋ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ํฐ๋ง
fabric version 1.4๋ฅผ ์ฌ์ฉํ์๊ณ , ๊ณผ์ ์ ์๋ตํ๋ค.
eventsclient.go์ ๊ณต๋ ํ์ผ eventsclient.go๋ฅผ ์์ ํ๋ค.
๋ชจ๋ ์์ค๋ ํ๋จ ๋งํฌ์ ์๋ค.
configtx.yaml์ ํ์ผ ๋ช
์ค์ // eventsclient.go
const (
OLDEST = -2
NEWEST = -1
ROOT = "configtx"
)
// eventsclient.go
// ์ด๋ฒคํธ ์์ PEER ์ค์ host:port
// + /etc/hosts ํ์ผ์ PEER ์ถ๊ฐ
flag.StringVar(&serverAddr, "server", "peer0.org1.example.com:7051", "The RPC se
rver to connect to.")
// ์ด๋ฒคํธ ์์ CHANNEL ์ค์
flag.StringVar(&channelID, "channelID", "mychannel", "The channel ID to deliver
from.")
// server.key, server.crt, ca.crt||ca.pem ๊ฒฝ๋ก ์ค์
flag.StringVar(&clientKeyPath, "clientKey", "/crypto-config/peerOrganizations/or
g1.example.com/peers/peer0.org1.example.com/tls/server.key", "Specify path to th
e client TLS key")
flag.StringVar(&clientCertPath, "clientCert", "/crypto-config/peerOrganizations/
org1.example.com/peers/peer0.org1.example.com/tls/server.crt", "Specify path to
the client TLS certificate")
flag.StringVar(&serverRootCAPath, "rootCert", "/crypto-config/peerOrganizations/
org1.example.com/peers/peer0.org1.example.com/tls/ca.crt", "Specify path to the
server root CA certificate")
// eventclient.go
var mspMgrConfigDir = "/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp"
var mspID = "Org1MSP"
var mspType = "bccsp"
export FABRIC_CFG_PATH=~/fabric-samples/first-network
์ ๊น์ง ์งํํ ํ ์คํํ๋ฉด, PEER์ commit ๋ฐ์ ์ BLOCK ์ ๋ณด๊ฐ console์ ๋ํ๋๋ค.
BLOCK์์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํด์ ์ฌ์ฉํ ๊ฒ์ด๋ค. (write set)
saveFilteredLog() : JSON Parsing function
์ ๋ฉ์๋๋ JSON์ Parsingํ์ฌ .log ํ์ผ๋ก ์ ์ฅํ๋ค.
๋ณธ ๊ธ์์๋ Docker๋ฅผ ์ด์ฉํ์ฌ EventListener๋ฅผ ํ์ฑํ ์ํฌ ๊ฒ์ด๋ค.
EventListener๋ฅผ Docker containerํ ์ํค๋ ์์
์ด๋ค.
EventListener์ image๋ eventsclient.go๋ฅผ ์คํํ๊ธฐ์ํ ํ๊ฒฝ ์
ํ
์ด ๋์ด ์๋ค.
docker-eventlistener.yamlvim docker-eventlistener.yaml
version: '2'
services:
eventlistener:
container_name: eventlistener
image: eventlistener:1.0
command: go run /eventsclient.go
volumes:
- ./crypto-config:/crypto-config
- ./eventdir/log:/log
- ./eventdir/eventsclient.go:/eventsclient.go
extra_hosts:
- peer0.org1.example.com:192.168.56.20
docker-compose -f ./docker-eventlistener.yaml up -d
docker logs -f eventlistener
๋ค์๊ณผ ๊ฐ์ ๋ก๊ทธ๊ฐ ๋จ๋๋ค.
{
"data": {
"data": [
{
"payload": {
"data": {
"actions": [
{
...
},
๋ํ docker-eventlistener.yaml์์ ์ง์ ํ ๊ฒฝ๋ก๋ก logํ์ผ 2๊ฐ๊ฐ ๋จ๋๋ค.
cd $PATH/eventdir/log
ls
# blockhistory.log filteredblockhistory.log
ELK Stack์ ํ์ฑํ ์ํจ๋ค.
๋ณธ ๋ฌธ์๋ ELK Stack์ Docker๋ก ์คํํ๋ค.
# Native
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.2.0-linux-x86_64.tar.gz
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.2.0.tar.gz
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.2.0-linux-x86_64.tar.gz
tar -zxvf elasticsearch-7.2.0-linux-x86_64.tar.gz
tar -zxvf logstash-7.2.0.tar.gz
tar -zxvf kibana-7.2.0-linux-x86_64.tar.gz
# Docker
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.2.0
docker pull docker.elastic.co/logstash/logstash:7.2.0
docker pull docker.elastic.co/kibana/kibana:7.2.0
docker-compose.yamlversion: '2.2'
services:
elasticsearch01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
container_name: elasticsearch01
environment:
- node.name=elasticsearch01
- cluster.initial_master_nodes=elasticsearch01
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/data/:/usr/share/elasticsearch/data
ports:
- 9200:9200
kibana:
image: docker.elastic.co/kibana/kibana:7.2.0
container_name: kibana
environment:
SERVER_NAME: kibana.example.com
volumes:
- ./kibana/config/:/usr/share/kibana/config/
ports:
- 5601:5601
depends_on:
- elasticsearch01
logstash:
image: docker.elastic.co/logstash/logstash:7.2.0
container_name: logstash
volumes:
- ./logstash/:/usr/share/logstash/
command: ./bin/logstash -f /usr/share/logstash/config/logstash.conf
ports:
- 5044:5044
- 9600:9600
depends_on:
- elasticsearch01
sudo sysctl vm.max_map_count=262144
docker-compose -f ./docker-compose.yaml up -d
network.host: 0.0.0.0
http.port: 9200
input {
beats {
port => 5044
}
stdin { }
}
filter {
json {
source => "message"
add_field => {
"%{key}" => "%{value}"
}
}
}
output {
elasticsearch {
hosts => ["192.168.56.10:9200"]
}
stdout {
codec => rubydebug
}
}
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://192.168.56.10:9200"]
ELK Stack๊ณผ Fabric, EventListener๋ฅผ ์คํํ๋ค.
Event๋ฐ์ ์, ์๋ก ์์ฑ๋๋ .logํ์ผ์ logstash์๊ฒ ๋๊ฒจ์ฃผ๋ ๋งค๊ฐ์ฒด๊ฐ ํ์ํ๋ค.
์ฐ๋ฆฌ๋ Filebeat๋ฅผ ์ฌ์ฉํ์ฌ ELK Stack๊ณผ Fabric์ ์ฐ๊ฒฐ ์์ผ ์ค ๊ฒ์ด๋ค.
Exception in thread "main" java.nio.file.AccessDeniedException
์์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋๋ค๋ฉด ํ์ผ ๊ถํ์ ํ์ธ!
docker pull docker.elastic.co/beats/filebeat:7.2.0
touch filebeat.yaml
vim filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/filteredblockhistory.log
multiline.pattern: "{\"write\":\"generated\"}"
multiline.negate: true
multiline.match: after
filebeat.config:
modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
filebeat.autodiscover:
providers:
- type: docker
hints.enabled: true
processors:
- add_cloud_metadata: ~
output.logstash:
hosts: "192.168.56.10:5044"
touch docker-filebeat.yaml
vim docker-filebeat.yaml
version: '2.2'
services:
filebeat:
image: docker.elastic.co/beats/filebeat:7.2.0
container_name: filebeat
command: filebeat -e -strict.perms=false
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml
- /var/run/docker.sock:/var/run/docker.sock
- /home/jack2/fabric-samples/first-network/eventdir/log:/var/log
docker-compose -f docker-filebeat.yml up -d
์ ๋ฆฌํ์๋ฉด, ์์ (mycc)์์๋ ์ด 2๊ฐ์ Key(a, b)๊ฐ ๋ณ๊ฒฝ๋๋ค.
Block์ Read/Write Set์๋ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ก์ ํ์ธํ ์ ์๋ค.
(value๋ base64 encoded ๋์ด์๋ค.)
"writes": [
{
"is_delete": false,
"key": "a",
"value": "OTA="
},
{
"is_delete": false,
"key": "b",
"value": "MjEw"
}
]
์ ์ ๋ณด๋ค์ด Filtered ๋์ด filteredblockhistory.log๋ก ์ ์ฅ๋๋ค.
{"write":"generated"}
{"is_delete":"false","key":"a","value":"90"}
{"write":"generated"}
{"is_delete":"false","key":"b","value":"210"}
Log ํ์ผ์ Filebeat๋ฅผ ํตํด Logstash๋ก ์ ๋ฌ๋๊ณ , ์ต์ข ์ ์ผ๋ก Elasticsearch์ ์ ์ฌ๋๋ค.
์ด์ , ์ ์์ ์ผ๋ก Elasticsearch์ ์ ์ฅ๋์๋์ง ํ์ธ ํ ๊ฒ์ด๋ค.
ํ์ธ์ Kibana(Elasticsearch์ ๋ชจ๋ํฐ๋ง ํด)์ ์ด์ฉํ๋ค.
์ธํฐ๋ท ๋ธ๋ผ์ฐ์ ์์ Kibana๊ฐ ํ์ฑํ ๋์ด ์๋ port๋ก ์ ๊ทผํ๋ฉด ๋๋ค.
๋ณธ ์์ ๋ฅผ ๊ทธ๋๋ก ๋ฐ๋ผํ๋ค๋ฉด 192.168.56.10:5601 ์ ํตํด Kibana๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์๋์ ๊ฐ์ด ์ด 2๊ฐ์ Key์ ๋ํ ๋ณ๊ฒฝ์ด ์ ์ฅ๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
๊ฐ๊ฐ์ txn์ ๋๋ฌ ํ์ธํด ๋ณธ๋ค.
Kibana์ ์ฌ์ฉ๋ฒ์ ์ตํ๋ค๋ฉด ํจ๊ณผ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ํฐ๋ง, ๊ด๋ฆฌ ํ ์ ์๋ค.
๋ชจ๋ ์์ค๋ ๊นํ๋ธ์ ์ฌ๋ ค๋์๋ค.