Hatena::ブログ(Diary)

Lazy Programmer :-p

 

2015-09-02

Docker で Sensu + Graphite + Grafana 環境構築

監視環境を新規に構築するにあたり、上記構成で環境を構築したのでそのメモです。

こんな感じでサーバの状況を確認できたり、

f:id:tomyhero:20150902150733p:image:w360

Slackにアラートの通知がきたり(メールも)

f:id:tomyhero:20150902150734p:image:w360

まで、ふんわりできました。以下、作ったDockerfile群

  1. https://github.com/tomyhero/docker-sensu
  2. https://github.com/tomyhero/docker-sensu-dashboard-uchiwa
  3. https://github.com/tomyhero/docker-sensu-dashboard-graphite
  4. https://github.com/tomyhero/docker-grafana

以下が、セットアップ手順です。

手順1: graphiteのセットアップ

git clone https://github.com/tomyhero/docker-sensu-dashboard-graphite.git
cd docker-sensu-dashboard-graphite
docker build -t tomyhero/sensu-dashboard-graphite . 
docker run --name sensu-dashboard-graphite -it -d \
    -v /opt/graphite/data:/app/graphite \
    -p 10200:80 \
    -p 2003:2003 \
    -e "ROOT_USER_NAME=tomyhero"  \
    -e "ROOT_PASSWORD=mysecret" \
    -e "ROOT_EMAIL=tomohiro.teranishi@gmail.com" \
tomyhero/sensu-dashboard-graphite bash

  • hostの /opt/graphite/data 配下に永続データ(統計データ)の保存
  • webを 10200 portでアクセスできるようにし、host側のnginxでproxyします
  • 2003 port は carbon-cacheに対して、コマンドを送るため

手順2: sensuのセットアップ


get clone https://github.com/tomyhero/docker-sensu.git
cd docker-sensu
docker build -t tomyhero/sensu .

docker run --name sensu -it -d \
-p 5672:5672 \
-p 4567:4567 \
-e GRAPHITE_HOST=$(docker inspect --format {{.NetworkSettings.IPAddress}} sensu-dashboard-graphite) \
-e "MAIL_TO=tomohiro.teranishi@gmail.com" \
-e "START_SENSU_CLIENT=false" \
-e "DASHBOARD_URL=http://uchiwa.localhost/" \
-e "ON_SENSU_HANDLER_NOTIFICATION_SLACK=true" \
-e "SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXX/XXXXXXXXXXXXX" \
tomyhero/sensu bash

  • 5672port は rabbitmq です
  • 4567port は API用です
  • $(docker inspect --format {{.NetworkSettings.IPAddress}} sensu-dashboard-graphite) graphiteのIPの出力
  • sensu clientを起動するなら START_SENSU_CLIENT=true
  • dashboard urlには あとででてくるuchiwaのURLを記載。
  • ON_SENSU_HANDLER_NOTIFICATION_SLACK - slackへの通知を有効にする場合 true に
  • SLACK_WEBHOOK_URL slackのwebhook urlを記載
  • その他必要に応じての設定は、https://github.com/tomyhero/docker-sensu ドキュメントで確認。

手順3: uchiwaのセットアップ


git clone https://github.com/tomyhero/docker-sensu-dashboard-uchiwa.git
cd docker-sensu-dashboard-uchiwa
docker build -t tomyhero/sensu-dashboard-uchiwa . 

docker run --name=sensu-dashboard-uchiwa -it -d \
-p 11003:3000 \
-e="SENSU_HOST=sensu.localhost" \
tomyhero/sensu-dashboard-uchiwa

  • 11003 portでwebにアクセス

手順4: grafanaのセットアップ

git clone https://github.com/tomyhero/docker-grafana.git
cd docker-grafana

docker build -t tomyhero/grafana .
docker run --name grafana -it -d -p 13000:3000 \
    -v /opt/grafana/data:/app/grafana \
    -e "GRAFANA_ADMIN_USER=tomyhero" \
    -e "GRAFANA_ADMIN_PASSWORD=secret" \
    -e "GRAFANA_AUTH_BASIC_ENABLED=false" \
    tomyhero/grafana bash 

  • hostの /opt/grafana/data 配下に、grafanaの設定データを保存
  • GRAFANA_AUTH_BASIC_ENABLED は環境に応じて。。。

手順5: sensu clinent

centosの環境なら

wget -O https://raw.githubusercontent.com/tomyhero/docker-sensu/master/bin/client-install-centos.sh
chmod 775 client-install-centos.sh
./client-install-centos.sh

/etc/sensu/config.json 作成。中身は自分で。

{
  "rabbitmq": {
    "host": "localhost",
    "vhost": "/sensu",
    "user": "sensu",
    "password": "secret"
  }
}

/etc/sensu/conf.d/client.json を作成。中身は自分で。

{
  "client": {
    "name": "tool",
    "address": "localhost",
    "subscriptions": [
      "basic","nginx","mysql"
    ]
  }
}

起動

service sensu-client start
tail -f /var/log/sensu/sensu-client.log

手順6: hostのnginx設定

upstream grafana {
  server localhost:13000;
}

upstream sensu {
  server localhost:11002;
}
upstream uchiwa {
  server localhost:11003;
}

upstream graphite {
  server localhost:11004;
}

// これと同じ感じを graphite,uchiwa,grafana でも用意
server {
  listen *:80;
  server_name sensu.localhost;

  access_log  /var/log/nginx/sensu.localhost.access.log main;
  error_log   /var/log/nginx/sensu.localhost.error.log;

  set_real_ip_from 10.0.0.0/8;
  real_ip_header   X-Forwarded-For;

  location / {
          proxy_read_timeout    300;
          proxy_connect_timeout 300;
          proxy_redirect        off;

          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host              $http_host;
          proxy_set_header X-Real-IP         $remote_addr;
          proxy_pass http://sensu;
  }

}

まとめ

取り急ぎ、サーバの状態の把握、状態異常の通知を受け取る環境が、dockerで簡単に作れるようになった。

sensu clientが落ちた時の通知、sensu server等が落ちた時等にどうするんだとかも、そのうち考えないと。

あと、自分用品質のDockerfileなので、ちょいちょい変更が入りそう。

2015-06-23

goji ミドルウェアー内で404の判断を、ServeHTTPの手前でする方法

routerのmatch処理前のフックになるので、

冗長だけど、matchを自分ですればできるって話

  1. goji.DefaultMux.Router を読み込む
  2. web.GetMatch(*c) が動作するようになるので、それを活用
package main
 
import (
    "fmt"
    "github.com/zenazn/goji"
    "github.com/zenazn/goji/web"
    "net/http"
)
 
func main() {
 
    goji.Get("/hello/:name", hello)
    goji.Use(goji.DefaultMux.Router)
    goji.Use(Check)
    goji.Serve()
}
 
func hello(c web.C, w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
}
 
func Check(c *web.C, h http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        pattern := web.GetMatch(*c).Pattern
        if pattern != nil {
            fmt.Println("ok")
        } else {
            fmt.Println("404")
        }
        h.ServeHTTP(w, r)
    }
    return http.HandlerFunc(fn)
}

2015-03-18

XCode6とSwiftで、viewControllerの上にviewControllerをポップアップみたいに出すやつ

ポップアップみたいなのを、実現したかったので適当に作った。

透明のレイヤーをかぶせたりしていて、もっと全うにできる方法が別にあるのかもしれない。

ボタンだけあって、おせる。

f:id:tomyhero:20150318230716p:image

押すと、これがでる。青いエリアがView。その上に見えないけど、buttonを配備している。見えない閉じるボタン。

f:id:tomyhero:20150318230715p:image

二つviewControllerを作る。ポップアップを開くボタンを作って、関連付けをする。present Modally ってやつ。

f:id:tomyhero:20150318230718p:image

で、こんな感じ。


f:id:tomyhero:20150318230719p:image


Presentationを、Over Current Contextにしておかないと、一つ目のviewControllerの描画をしないかんじになって、真っ黒になってまうので、設定が必要。


f:id:tomyhero:20150318230720p:image

あと、ViewとButtonのBackgroundを Defaultにしておくこと。透明にするために。

ポップアップを、透明の背景ボタンを押したら閉じるように、閉じるしょり。

    @IBAction func close(sender: AnyObject) {
        self.dismissViewControllerAnimated(false, completion: nil)
    }

とりあえず、動く。いいやり方なのかわからないけど。

https://github.com/tomyhero/xcode-sandbox/tree/master/PopUp

2015-03-17

XCode6で Bundle Identifier の名前とかを変更する

Bundle Identifierの値は、素直な感じに変更できない。

f:id:tomyhero:20150318003744p:image

Unkoとかのままにしたくない。

f:id:tomyhero:20150318003745p:image

Product Nameの Unkoを Lazy に変更する。

f:id:tomyhero:20150318003744p:image

そうすると、Bundle Identifier が変更される。

f:id:tomyhero:20150318003746p:image

ただ、まだUnkoにまみれてる。

f:id:tomyhero:20150318003747p:image

右上の、xcodeproje ファイルの名前を変更すると、以下のように他変更する提案をしてきてきて、素敵。

f:id:tomyhero:20150318003748p:image

いうても、まだ Unko いっぱいいるので、手動で Lazyに全部何も考えずrenameしていく。

UnkoTests.swift のファイル名だけではなく、中身のクラス名もrenameするのわすれずに。

だいたい、画面からはUnkoがきえた。

f:id:tomyhero:20150318003749p:image

ファイルシステムから、調べる。うようよいる。置換をコンソールからガンガンやってみる。

f:id:tomyhero:20150318003751p:image

f:id:tomyhero:20150318003750p:image

バイナリーのファイル以外は、全部なおした。バイナリーのは、まぁ、適当にほっとく。

f:id:tomyhero:20150318003752p:image

起動成功した!

f:id:tomyhero:20150318003753p:image

これで、気兼ねなく、適当に名前をつけて、後で変更できるね。

自己責任だけどね!

2012-07-03

Cacheクラス

前回作った、configクラスを使いつつ、シングルトン化し、

ブロックの結果をキャッスする関数を生やしたかんじ。

ソース

require 'singleton'
require 'memcache'
require 'bei/config'
require 'pp'

module Bei
  class Cache < Memcache
  include Singleton

  def initialize
    super ( { :servers => Bei::Config.instance.get(:memcached_servers) } )
  end


  def cacheable(key,expire=60*3)
    raise "NO_BLOCK_ERROR" unless block_given?

    unless( value = self.get(key) )
      #pp 'from value'
      value = yield()
      self.set(key,value,expire)
    else
      #pp 'from cache'
    end

    return value
  end

  end

使い方

こんな

かん


 cache = Bei::Cache.instance() 
# Memcache の継承なので、既にある関数はそのまま使える。
 cache.set('hi','hihihi')
 hi = cache.get('hi')

 # blockからデータ取得
 my_data = cache.cachable('my/3/data', 60 * 1) { { :user_id => 3 } } # 3 

 # memcachedからデータ取得
 my_data = cache.cachable('my/3/data', 60 * 1) { { :user_id => 2 } } # 3 (2じゃない)