nemunemu_zzzの日記

備忘録的な何かになればいいな

golangのinterface{}の不思議

golangを触り始めて約3ヶ月

interface{}が便利なのでよく使います

 

ただ最初はinterface{}の挙動がよくわかってなくて使うたびに苦戦してたのでメモメモ_φ(・_・

 

package main

import(
  "fmt"
)

func main() {
  Output("string")
  Output(100)
  Output(true)
}

func Output(x interface{}) {
  fmt.Println(x)
}

=> string
100
true

特に型を宣言しなくてもなんでもこーい!なことができる

すごい便利

 

ただ, もし受け取った関数で型がしっかりと指定しないとダメなケースがある

大体がこのパターン, だから便利だけとメンドくささもある

例えば次のような場合

package main

import(
  "fmt"
)

func main() {
  Output(100)
}

func Output(x interface{}) {
  fmt.Println(x*2)
}

=> # command-line-arguments
./test.go:12:16: invalid operation: x * 2 (mismatched types interface {} and int)

interface{}型とint型では計算できませんよって怒られます

なんでも受け取ってくれるのに実は繊細なのかなって感じです

解決作

package main

import(
  "fmt"
)

func main() {
  Output(100)
}

func Output(x interface{}) {
  fmt.Println(x.(int)*2)
}

=> 200
 

変数の後ろにx.(int)と, interface{}型で受け取ったけど, この子はint型ですよーって書いてあげれば大丈夫

主にswitchを使って分岐処理をさせることが多いです

    package main

import(
  "fmt"
)

func main() {
  Output("aaaaaaa")
  Output(100)
  Output([]string{"a", "b", "c"})
}

func Output(x interface{}) {
  switch v := x.(type) {
  case string:
    fmt.Println(v)
  case int:
    fmt.Println(2*v)
  case []string:
    fmt.Println(v)
  }
}

=> aaaaaaa
200
[a b c]

こんな感じで変数の型(type)によって処理を分岐させます

あともう1つ詰まったところがあり, それが配列のinterface{}

[]interface{}ってやっとけば, stringだろうがintだろうがboolだろうがうけとってくれるやろーって

package main

import(
  "fmt"
)

func main() {
  Output([]string{"a", "b", "c"})
  Output([]int{100, 200, 300})
  Output([]bool{true, false})
}

func Output(x interface{}) {
  switch v := x.(type) {
  case []interface{}:
    fmt.Println(v)
  default:
    fmt.Println("ハズレ")
  }
}

=> ハズレ
ハズレ
ハズレ

そうはうまくいかないんですね

見事にスルーされてます(泣

実は[]interface{}型の配列であれば受け取ってもらえます

package main

import(
  "fmt"
)

func main() {
  Output([]interface{}{"test1", 100, true})
}

func Output(x interface{}) {
  switch v := x.(type) {
  case []interface{}:
    fmt.Println(v)
  default:
    fmt.Println("ハズレ")
  }
}

=> [test1 100 true]

interface{}型の配列が存在するために, 配列の型なんでもこーいって形で使用することができないのかなって感じです

というな感じで, interface{}と戯れてましたってお話でした

interface{}は便利

リーダブルコード読んでみた

インフラ構築などが好きでプログラムを書くのが嫌いでした.

ただ, 最近はプログラマーもインフラを触れるようになってきている時代, ある程度は書けるようにならなきゃなぁ...っと思い言語を復習したり, Railsやswiftでアプリを作ってみたりしているうちにコード書くのも楽しく思えてきました.

ただ, 自分一人で完結するものばかり書いてたので, ものすごーーーーく汚かったw

リファクタリング?何それ, 美味しいの?」ってレベルです

自分で書いてても何がなんだがわからないことばかり(笑)

しかし, 仕事で使うようになってこのままじゃダメだと思い, よく聞く良本「リーダブルコード」を買って読んでみた.

1章読むたびに, 「ごめんなさい...m(_ _)m」って気持ちになりました(笑)

 

直さなきゃいけないポイントがいっぱいあるんですが, 自分の中で少なくともこれだけは気をつけようと思ったポイントは3点

  • 変数の名前
  • ネストを深くしない
  • コードの重複を避ける

これだけは何がなんでも気をつけると心に誓いました.

自分のコードを見ると,

  • 変数名は「a」,「hoge」, 「hoge2」,「fuga」, 「piyo」...など
  • forの中にfor, ifが大量発生
  • main関数に全部書くから重複だらけ

力技だけで動いているものばかり, 目も当てられない_:(´ཀ`」 ∠):

実際にこの3点を気をつけるだけで, コードの見通しがかなりましになりました.

コード書くセンスないからを言い訳にせずに, せめて誰かに見せた時に「最高」とまでは厳しいですが「読めなくはない(笑)」といわれるように頑張りたい...!

 

リーダブルコードは読んで良かった思えた1冊でした

リーダブルコード

XSS gameやってみた

たまたま授業でXSSのデモをすることになり, 色々勉強しているときにXSS gameの存在を教えてもらったので遊んでみました

3問まではわりとさくさくいけたけど, 4問目からは簡単には解けなくなった(笑)

いろいろ調べながら全問解くことができてよかった(笑)

codeとhintが見れるのでやりさやすさも難易度もだれずにがんばれるちょうど良いものだったなぁ~と思いました

rails のActionCableを使ってリアルタイムなアプリを作ろうとした話

railsを使って, DB情報をリアルタイムに画面に表示してくれるアプリを作ろうと思いました

最初はAngler.jsを使おうと思ったり, Ajaxを使おうと思ったりしたけど調べているうちにActionCableなるものを発見しました

ActionCableはWebSocketを簡単に実装できるようにしてくれるものであった. 今回やりたいことに一番近いかなと思い使うことにしました

調べてみるとサンプルが多くあり, 簡単にチャットアプリを作ることができました

こことか参考

実際に入力フォームからDBに格納されて, 表示までされました

ただ今回作りたいもの的にDBが直に更新された時に, ブラウザ側は更新されるのかが気になり, consoleからDBの中身を追加して試してみました

結果, データはブラウザに送られているっぽいけど, 画面をリロードしないと反映されなかった...

いろいろ調べてがんばってみたけど, どうしてもうまいこと対処することができなかった

そこで取った方法が


setInterval("location.reload()",60000);

jsでムリヤリ画面をリロードさせるっていうダサい実装となってしまった(笑)

やりたいことはできたけどWebSocket使ってるのになんだかなぁ~って感じですっきりしない...

もっとスマートなやり方を見つけていきたい...

サーバをブリッジとして扱う

サーバ3台を2台ホスト, 1台ブリッジとして構成する

ブリッジの設定についてメモしておく

 

環境

  • CentOS7

 

参考サイト

http://kashigeru.hatenablog.com/entry/2014/02/12/224728

http://d-net.robata.org/inetbuild-bridge.html

 

まず, bridge-utilsをインストー

# yum install bridge-utils

インストールするとbrctlコマンドが使える

ブリッジの設定を行っていく

ブリッジを追加

# brctl addbr br0

 

Interfaceを設定する

# brctl addif br0 enp3s0
# brctl addif br0 enp5s0

 

ブリッジにIPを振る

# ip addr add 10.0.0.2/24 dev br0

 

Interfaceも設定

ip addr add 0.0.0.0/24 dev enp3s0
ip addr add 0.0.0.0/24 dev enp5s0

 

ブリッジを有効にする

ip link set br0 up

 

これでホスト間での同じネットワーク帯での通信が行えた

elasticsearchのtimestampとkibanaでのtimestampがずれてしまう

filebeatのmoduleを使っていて, Kibanaで見てみると未来のデータありました(笑)

サーバーのlogは JST,
Elasticsearchは UTC,
Kibanaは JST
となる

未来のデータを見てみると, どれも/var/log/messages, /var/log/secure だけだった.

よくよく見ると, サーバーのlogの時刻をUTCに変換せずにElasticsearchに入り, Kibanaに+09:00されたデータが入っているようだ.

syslogのmoduleがおかしそうだな

調べて見ると, moduleはIngest Nodeというものを使っていて, 各moduleの下のingest/ 以下の.jsonに設定があるようだ

参考にしたサイト

https://discuss.elastic.co/t/filebeat-assumes-utc/80896

上記のサイト参考に /usr/share/filebeat/module/system/syslog/ingest/pipeline.json を書き換えてみる

# vi /usr/share/filebeat/module/system/syslog/ingest/pipeline.json

変更前

   
    "date": {
        "field": "system.syslog.timestamp",
        "target_field": "@timestamp",
        "formats": [
                        "MMM  d HH:mm:ss",
                        "MMM dd HH:mm:ss"
        ],
        "ignore_failure": true
    }

変更後

   
    "date": {
        "field": "system.syslog.timestamp",
        "target_field": "@timestamp",
        "timezone": "Asia/Tokyo",
        "formats": [
                        "MMM  d HH:mm:ss",
                        "MMM dd HH:mm:ss"
        ],
        "ignore_failure": true
    }

ちなみに"timezone": "JST"だとエラーが出てダメだった...orz

上記のように編集したらElasticsearchの古いpipeline情報を削除します

# curl -XDELETE http://<yourIP>:9200/_ingest/pipeline/filebeat-5.5.0-system-syslog-pipeline

次にfilebeatを再起動してお終い!

# systemctl restart filebeat

一度elasticsearch側に登録さえしてしまえば, 他のサーバのfilebeatは再起動するだけでok

僕は,サーバごとでfilebeatのバージョンが違って少し詰まってしまいました(笑)

起動しているかも確認

# systemctl status filebeat

pipelineがちゃんと設定されてたかも見てみる

# curl -XGET http://<yourIP>:9200/_ingest/pipeline/filebeat-5.5.0-system-syslog-pipeline
    {"filebeat-5.5.0-system-syslog-pipeline":{"description":"Pipeline for parsing Syslog messages.","on_failure":[{"set":{"field":"error","value":"{{ _ingest.on_failure_message }}"}}],"processors":[{"grok":{"field":"message","ignore_missing":true,"pattern_definitions":{"GREEDYMULTILINE":"(.|\n)*"},"patterns":["%{SYSLOGTIMESTAMP:system.syslog.timestamp} %{SYSLOGHOST:system.syslog.hostname} %{DATA:system.syslog.program}(?:\\[%{POSINT:system.syslog.pid}\\])?: %{GREEDYMULTILINE:system.syslog.message}","%{SYSLOGTIMESTAMP:system.syslog.timestamp} %{GREEDYMULTILINE:system.syslog.message}"]}},{"remove":{"field":"message"}},{"date":{"field":"system.syslog.timestamp","formats":["MMM  d HH:mm:ss","MMM dd HH:mm:ss"],"ignore_failure":true,"target_field":"@timestamp","timezone":"Asia/Tokyo"}}]}}

設定が反映されていることがわかる

kibanaからもちゃんとできていることが確認できた

Elastic Stack導入してみた

備忘録的に残します.

 

今回ログサーバーを構築しようと思い, Elasic stack(beats + Logstash + Elasticsearch + Kibana)を使ってみようと思いました.

まだ細かい設定とかは全然してないけど, installと一通りの流れだけまとめときます.

まぁ,公式のドキュメント通りでした(笑)

 

環境

  • Kibana 5.4.1
  • Elasticsearch 5.4.1
  • Logstash 5.4.1
  • Filebeat 5.4.1
  • CentOS7系

 

私はrpmで導入したため, 下記のドキュメントを参考にしました

Kibana

elasticsearch

logstash

filebeat

 

基本的な流れとしては

 

鍵をもってきて

# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

 

レポジトリを作って

# vi /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

 

インストールするだけ

yum install elasticsearch

 

インストールが終わった自動起動の設定やサービスの起動

# yum enable elasticsearch
# yum start elasticsearch

 

elasticserachのstartでハマッてしまってつらかった...

statusを見るとメモリーが足りないというエラーが発生してました

私はelasticsearch4系のときはすんなり起動してくれていたからうまくいくはずだ...!ってずっとハマってしまいました(笑)

元はメモリは1Gだったのですが, 4Gに上げたら起動してくれました

このサイトを参考にしました. デフォルト2Gもあればそりゃむりよね(笑)

http://www.karakaram.com/elasticsearch-memory-usage-reduce

 

 

設定ファイル関連

 

elasticsearch.yml

# vi /etc/elasticsearch/elasticsearch.yml
    #network.host: 192.168.0.1
    network.host: 
        
    #http.port: 9200
    http.port: 9200

 

kibana.yml

# vi /etc/kibana/kibana.yml
    #server.host: "localhost"
    server.host: ""

filebeat.yml

# vi /etc/filebeat/filebeat.yml
    output.elasticsearch:
  # Array of hosts to connect to.
  hosts: [":9200"]

 

portの開放

    
    firewall-cmd --add-port=5601/tcp --zone=public --permanent
    firewall-cmd --add-port=9200/tcp --zone=public --permanent
    firewall-cmd --reload

 

これでkibana上での可視化までの流れは見えたので, 転送するファイルや, indexの設定やらの細かいのはまた今度!

beatsが色々できるっぽいのでzabbixとの比較だったり色々試していきたいなぁ