Skip to main content

3 posts tagged with "grafana"

View All Tags

· 11 min read

제목은 저렇지만 정확히는 Xiaomi 온습도 센서로 측정한 값을 Smart Things가 받고 그걸 InfluxDB에 저장해서 Grafana로 그린다가 되겠다. 해놓고 나니 이게 큰 의미가 있나 싶지만 준비해 놓은지는 꽤 되었으니 정리하는 차원에서. 성공한 기업가들이 내가 하고 싶은걸 하지 말고 고객이 원하는걸 하라고 했다는데 그 말이 맞다는 생각이 문득 든다.

원래 집안에 이런 저런 장비들을 엮어볼 생각으로 Smart Things를 구매해 놨었는데 zigbee나 zwave를 지원하는 센서 종류는 다 붙일 수 있는 걸로 알려져있다. 물론 공식적으로 지원하는 종류들이 있고 그 외에는 무언가 수를 써줘야만 가능하다. Smart Things는 내부적으로 Device Type Handler 라는걸 만들어줘야 하는데 주변 장치들과 주고받는 데이터의 형태를 정의한 내용 정도로 이해하고 있다. 공식적으로 지원하는 장치들은 그 DTH 라는게 제공되고 그렇지 않은 장치들은 만들어주던가 해야하는데 그 DTH가 정의되어 있지 않아도 Smart Things에서 장치 찾기를 하고 있는 상태에서 해당 장치를 페어링 하려고 시도하면 날라오는 zigbee 기반의 데이터는 볼 수 있다.

Pairing

그런데 Smart Things에서 공식 지원하는 센서들이 꽤 비싸다. 상대적으로 Xiaomi에서 나오는 센서들은 개당 만원정도로 저렴. Xiaomi 센서들도 zigbee 기반이고 기본은 Xiaomi의 home gateway 뭐 이런 장비들과 붙여 쓰라고 나온거지만 능력자님들께서 Smart Things에 붙일 준비를 다 해놓으셨다. Xiaomi의 gateway는 그네들의 제품들을 붙여 쓰기엔 좋겠지만 다른 제품군은 지원하지 않고 뭔가 내가 제어를 해보려고 하면 전용앱으로만 가능한 듯 해서 일찌감치 gateway는 포기했고 Smart Things로 시도. Github에 올라가 있는 DTH만 가져다쓰면 페어링은 어렵지 않다.

Smart Things의 구조에 따른 데이터 전달

Smart Things는 언뜻보면 요상한데 Box 형태라서 연결된 장치들에 대한 제어나 장치로부터의 데이터 수집은 box에서 이루어질 것 같지만 box 자체에 접근할 방법이나 api 같은게 없다. 그러니까 쉽게 raspberry pi 처럼 생각해서 내부에서 웹서버 같은게 하나 돌고 rest api를 제공하는게 쉬울 것 같은데 전혀 다르게 Smart Things에서 서비스하는 developer console을 통해서만 제어든 뭐든 가능하다. 그것도 application이라는 이름으로 만들어줘야 한다. 쓰다가 생각해보니 Amazon의 echo와 비슷하다. Box는 거의 깡통이고 받은 데이터는 위로 올리고 (심지로 로그까지), 스마트폰 전용 app에 개인이나 다른 사람이 만들어서 공개한 app (app내 app)을 설치하고 나면 그 app에서의 조작에 따라 Smart Things를 통해 box로 내려오는 걸로 보인다. 단순히 보면 이런 모양.

데이터를 가져와야 하나 보내줘야 하나

문제는 DTH를 포함해 app을 만드는 것도 groovy 기반의 DSL을 사용해야만 한다는 사실이다. 이미 정의된 형태의 UI (tile)들이 있고 groovy로 개발할 때 다른 library 들을 불러오는데 제약이 있다. 또 file io 등 시스템 자원에 대한 접근이 불가능하다. 대부분 필요할 것 같은 기능들은 이미 준비되어 있으니 준비해둔 메소드나 클래스를 가져다 쓰라고는 되어있는데 완전 새로운 언어를 익히는 느낌이고 디버깅이 힘든데다가 로그까지 브라우저에서 별도의 메뉴로 진입해 확인해야 하니 불편하다. (이런 방식이 편한 사람이 있을지도 모르겠다) 센서로부터 수집된 데이터들은 (사실 이런 용도로 만들어진 제품이 아니라는 생각도 들지만) box나 Smart Things 내부에 쌓이는게 아니기 때문에 Smart Things 서비스에 접근해서 받아오거나 반대쪽으로 보내줘야만 한다. 구조상 두번째 방법이 가능성이 있어보여서 groovy로 app을 하나 만들었다. Smart Things 모바일 앱 내부에서 보면 아래 그림처럼 이벤트가 발생하는 센서 종류를 선택하고 데이터를 보낼 곳을 지정하게 했다. 그림에는 보이지는 않지만 InfluxDB에 저장할거라 db 이름과 username, password까지.

데이터를 저장했는데 주기가 문제

InfluxDB에 데이터가 저장되기 시작하면서 Grafana를 붙여 차트를 그려봤는데 문제가 생겼다. Xiaomi 센서가 주기적으로 측정하지 않고 주기를 조정할 방법이 없어서 차트가 볼품이 없다. 온도나 습도가 어느 정도 수준 이상의 변화가 있을 때만 측정한다고 알려져있는데 빠르면 몇 분만에 측정하는 경우도 있지만 3시간 정도 측정하지 않는 경우도 생기기 시작했다. 센서 사이즈가 작고 전지를 쓰는 형태라 전력소모 문제로 그렇게 되어있는 듯 한데 도저히 조절할 방법이 안보여서 비싸지만 Smart Things의 센서로 교체해볼까도 생각해봤으나 그것도 동일하다고 해서 패스. 그래서 측정 문제로 해결할게 아니라 원본 데이터를 크게 왜곡하지 않는 선에서 볼품 없는 차트를 그럴듯하게 만들어보기로 했다. 어느 정도로 볼품이 없는지는 아래 그림이면 설명이 될 것 같다.

녹색 라인이 측정된 값으로 그려진 차트인데 좌측과 우측이 비어있다. 이전 3시간을 그린 건데 4번 정도 측정한 것으로 보이고 없는 구간은 찍힌 점이 없어서 그렇다. 이런 상태를 개선하기 위해서 5분 단위로 데이터를 grouping 하고, 그럼 데이터가 없으니 평균값을 사용해봤는데 그래도 개선은 안되고 (5분 단위로 쪼개려고 한 것은 위 그림의 노란색 라인이 다른 곳에서 받아오는 외부 온습도 데이터인데 5분 단위로 받아와 저장하기 때문에 맞춰주려고 시도한 것) InfluxDB의 fill 기능을 사용해서 빈 값을 이전 값으로 채워줬다. 이것도 문제는 있는게 이전 값으로 채우기 때문에 보여지는 time range에서 이전 값이 없는 경우 (시간 구간 중 초기 값)에는 여전히 비어있게 된다. 다음 값으로 채우는 옵션도 있으면 좋겠다 싶다. (관련된 내용은 InfluxDB 문서에도 이슈로 달려있음) 추가로 차트 종류도 변경했더니 처음보다는 보기가 훨씬 나아졌음.

Raspberry pi + sensor가 낫지 않나?

이런 생각을 잠깐 해봤는데 이렇게 하면 측정 주기 같은건 내 맘대로 할 수 있다. 복잡하게 Smart Things에서 app 같은거 안만들어도 되고. 그런데 이렇게 할 경우 여러개의 센서를 쓰려면, 예를 들어 방마다 센서를 두겠다 하면 raspberry pi도 센서 수만큼 필요해질 것 같다. 작게라도 보드를 만들어야 할 수도 있고, 전원 문제도 신경을 써야 한다. 역시 만들어진 걸 사서 쓰는게 그나마 편하다.

· 7 min read

잊을만하면 쏟아지는 T-mobile용 AC1900 짜리 ASUS 공유기. 이쯤이면 'T-mobile 그거'나 'ASUS 그거'라고 불려도 되지 않을까? 대부분 제조사 리퍼제품이거나 open box이거나 그렇지만 성능에 비해 매우 저렴하게 나와서 많이들 주문하는 것 같다. 쳐다보고 있자니 그것들이 쏟아지기 전에 원모델 중 하나(AC68U)를 요즘보다는 비싼 가격으로 구매했던터라 아쉬운 마음 뿐이다.

아무튼 얼마전에 아는 형님이 '그런 공유기' 모니터링 방법을 공유해주셨는데 멀린 펌업 => metric 수집 script 실행 (cron) => influxdb에 저장 => grafana에 표시하는 내용으로 요약할 수 있을 것 같다. 나의 경우 Asus 공식 펌웨어를 쓰고 있기 때문에 멀린 펌웨어로 올리는 과정이 필요한터라 SNMP로 어떻게 해보기로 했다.

SNMP를 지원하나?

많은 OS, 라우터 등의 장비들이 snmp를 지원하는 것으로 알려져있다. Asus 공유기라고 안될 이유는 없는데 관리 메뉴에는(있을법도 하지만) snmp on/off 라던가 설정에 대한 내용이 없다. 그럼 net-snmp 같은 패키지를 설치해서 돌려야 하는데 공유기가 많이 알려진 배포판 리눅스가 올라간게 아니라서 어떻게 설치할 수 있는지 패키지 이름은 뭔지 알 수가 없다.

Download master와 ipkg, 그리고 net-snmp의 설치

찾아보니 asus 공유기에서는 debian의 dpkg와 비슷한 ipkg를 사용할 수 있다고 한다. 그런데 이것 역시 기본적으론 설치되어 있지 않고 꼼수를 써야 가능하다. 먼저 공유기 뒷면에 있는 usb 포트에 스틱이든 하드든 꽂아준다. (단, 리눅스이므로 filesystem이 ext4나 ntfs 같은 형태여야 인식 가능) 공유기에서 인식을하면 download master를 설치할 수 있게 되는데 설치를 끝내면 연결한 외부 장치에 ipkg가 설치된다. (mount된 경로에 설치가 되기 때문에 빼면 안된다) ipkg로 net-snmp 설치 후 활성화하면 끝.

ipkg update
ipkg install net-snmp
app_set_enabled.sh net-snmp yes

수집은 어떻게?

SNMP를 통해 정상적으로 정보를 얻을 수 있는지는 간단하게 snmpwalk 등을 이용하면 확인할 수 있겠다.

지속적으로 정보를 수집해서 db에 쌓아야 하는데 별도로 스크립트를 만들어서 돌리기는 싫고 (이럼 처음부터 스크립트를 만들어 돌리지 굳이 snmp로 할 이유가 없다) 어차피 influxdb를 쓸 생각이었으니 같은 곳에서 만든 telegraf를 써보기로 했다. Telegraf는 docker container로 돌리고 output 설정은 이미 설치되어 있는 influxdb에 맞게, snmp input에 대해서는 아래처럼 해줬다.

[[inputs.snmp]]
agents = [ "xxx.xxx.xx.1:161" ]
version = 2
community = "public"

[[inputs.snmp.field]]
name = "hostname"
oid = "RFC1213-MIB::sysName.0"
is_tag = true

[[inputs.snmp.field]]
name = "uptime"
oid = "DISMAN-EXPRESSION-MIB::sysUpTimeInstance"

[[inputs.snmp.table]]
name = "interface"
inherit_tags = [ "hostname" ]
oid = "IF-MIB::ifTable"
[[inputs.snmp.table.field]]
name = "ifDescr"
oid = "IF-MIB::ifDescr"
is_tag = true

[[inputs.snmp.table]]
name = "interface"
inherit_tags = [ "hostname" ]
oid = "IF-MIB::ifXTable"
[[inputs.snmp.table.field]]
name = "ifDescr"
oid = "IF-MIB::ifDescr"
is_tag = true

[[inputs.snmp.table]]
name = "interface"
inherit_tags = [ "hostname" ]
oid = "EtherLike-MIB::dot3StatsTable"
[[inputs.snmp.table.field]]
name = "ifDescr"
oid = "IF-MIB::ifDescr"
is_tag = true

이렇게 하고 나니 telegraf의 문제인 것 같은데 IF-MIB라는 OID를 인식못하는 문제가 발생. Community에서 찾은 글을 참고해 따로 snmp-mibs-downloader를 설치해줬다. (Docker image를 새로 만드는게 나을 것 같긴 한데 제대로 되는지만 보려고 container 내부에 들어가서 설치 후에 container를 restart 해줌. 설정된 persistent volume에 변경된 내용이 저장되는 것인지 restart 해줘도 문제없었다)

InfluxDB에서의 확인

위와 같이 telegraf 설정을 한 경우 InfluxDB에서 확인을 해보면 (telegraf 기본 설정 중 inputs.cpu, inputs.disk 등을 제거하지 않은 경우) cpu, disk 등의 measurement 이외에 interface, snmp라는 measurement가 있는 것을 확인할 수 있다. 설정대로라면 snmp에는 host와 uptime 정보 정도, interface에는 network interface 별 정보들이 쌓이게 된다.

Grafana 연결과 dashboard 생성

Grafana에서 data source로 influxdb를 설정하고 나서 쓸만한 dashboard를 찾아보니 마땅한게 없다. SNMP에 대한 것들은 있어도 보통은 cpu, storage 정보 정도라 공유기에서 큰 의미는 없을 것 같아서 직접 추가하기로 했다. SNMP의 OID들을 좀 더 확인해봐야 더 재미있는 것들을 볼 수 있을 것 같은데 일단은 throughput과 uptime만. (지금은 수집해서 쌓는 것도 uptime이랑 interface 별 in/out packet 수 정도뿐)

참고

1. How to configure SNMP on Asus RT-AC68U

2. Using Telegraf, InfluxDB and Grafana to Monitor Network Statistics

· 7 min read

이전 글에서 docker monitoring을 하기 위해서 cAdvisor를 사용해봤는데 몇가지 단점들 때문에 바로 monitoring에 사용하기에는 문제가 있었다. 그래서 많이 사용한다는 prometheus를 사용해보기로 했다.

 

1. cAdvisor 정리

Prometheus를 사용하기 전에 먼저 cAdvisor를 정리해보면 아래와 같다.

(1) Container가 동작중인 host 각각에 설치 (클러스터링 안됨)

(2) Host와 container의 지표 모두 수집

(3) 수집된 지표들은 /metrics 경로에서 확인 가능

 

2. Prometheus

Prometheus는 docker container, VM 등을 모니터링할 수 있는 툴로 수집되는 지표들을 내부에 DB로 보관하는데 수집된 지표들을 확인하기 위해 PromQL이라는 쿼리를 제공하며 대략적인 구조는 아래 그림과 같다. Alert도 가능하다.

prom_architecture <출처 : https://www.ctl.io/developers/blog/post/monitoring-docker-services-with-prometheus>

Prometheus에서 중요하게 본 것은 그림에서의 "scrape metrics"를 어떻게 할 것이냐였는데 다행히 cAdvisor와의 연동은 prometheus 설정 파일에 cAdvisor의 metrics 경로를 지정해 주는 것으로 간단히 가능하고 별도로 container-exporter도 제공되고 있다. Container exporter를 사용할 경우 cAdvisor처럼 container로 올려줘야 하는데 Mesos, Marathon을 사용중이라면 Marathon으로 간단히 올려주면 되겠다. Container exporter는 cAdvisor와 유사하게 측정 지표들을 수집해서 /metrics 경로로 export 할 수 있는데 cAdvisor처럼 자체적으로 monitoring UI를 제공하지는 않는 것 같다. cAdvisor와는 수집하는 지표들이 차이가 있다. Prometheus 입장에서는 cAdvisor, container exporter 둘 중에 무엇이든 /metrics 경로에 접근해서 수집된 데이터들을 내부에 보관한다.

 

3. Prometheus 설치와 설정

(1) Install

Installing 페이지에 기술된 내용을 보면 release 된 파일을 다운로드해서 압축을 풀거나 source를 빌드해서 사용하거나 docker로 올리면 된다. 나의 경우엔 별도의 VM에 파일을 다운로드해서 사용했는데 linux 배포판 별로 버젼이 따로 없으므로 그냥 linux 용으로 되어있는 파일을 사용하면 된다. (macOS는 darwin)

(2) Configuration

문서들을 보면 설정파일(prometheus.yml)에서 다양한 설정을 지원하고 있는데 가볍게 cAdvisor와의 연동만을 해보고 싶다면 아래처럼 scape_configs section의 static_configs > targets 부분만 설정해도 가능하다. targets에는 cAdvisor가 동작중인 host와 port 정보만 넣어주면 prometheus는 yml 파일에 명시된대로 기본으로 /metrics 경로에 접근해서 측정된 지표를 가져온다. cAdvisor가 아니라 container exporter를 사용하고자 한다면 targets 부분만 변경해주면 되고 두가지 모두 사용해도 무방하지만 중복되는 지표가 많고 cAdvisor가 더 다양한 지표를 수집한다.

scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'mesosphere'

# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s

# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.

static_configs:
- targets: [
'cAdvisor_host1:port1',
'cAdvisor_host2:port2',
'...',
'...'
]

 

4. Prometheus UI

Prometheus 설정을 마치고 prometheus 파일을 실행하면 브라우저에서 UI를 확인할 수 있는데 cAdvisor에서 제공하는 지표들을 선택하고 PromQL을 사용해서 적절히 쿼리해야 한다.

prom_ui

시간 간격을 조절할 수 있고 원하는 그래프를 계속 추가해서 확인할 수는 있지만 그래프가 단순하고 cAdvisor처럼 바로 사용하기에는 뭔가 부족하다. 위 그림에는 제대로 표현되지 않았지만 cAdvisor가 수집하는 데이터 중 CPU usage의 경우 CPU core 별로 (cpu00, cpu01 등) 사용량을 수집하고 있어서 데이터를 가공할 필요가 있는데 이것은 PromQL로 해결해야 한다.

 

5. Grafana

Grafana는 단순히 dashboard를 편하게 만들고 관리할 수 있는 툴인데 data source 중 하나로 prometheus를 지원하고 있다. Prometheus에서 제공하는 grafana 설치 문서를 참고해서 설치한 후에 실행하고, 아래 그림처럼 data source 추가하는 부분에서 prometheus의 경로를 추가하면 된다.

grafana_datasource

Dashboard를 생성하면 빈 페이지가 나오는데 다양한 graph를 추가하고 설정할 때 graph를 그리기 위한 data는 prometheus에서 가져오게 되므로 PromQL을 적절히 사용해줘야 한다. (PromQL 문서 참조)

 

6. Grafana dashboard

Dashboard를 만들고 수정해보니 cAdvisor와 prometheus의 모니터링 측면에서의 부족한 부분들을 grafana가 모두 보완할 수 있다는 생각이 든다. Host와 container의 상태를 비교해보기도 좋고 시간 간격을 다양하게 변경할 수 있으며 훨씬 다양한 그래프를 사용하거나 아래 그림처럼 숫자만으로 혹은 테이블로 표시할 수도 있다.

granfana