実戦へのGo導入
TIME rest time current/total
TopicsPlaceHolder

実戦へのGo導入

GoCon 2015 winter

Dec 6th, 2015

Profile

songmu

Goで作ってるもの

 

Mackerel Advent Calendar参加者募集中です!!!

本題

実戦へのGo導入

Agenda

はてなのGo実績

はてな社内のGo実績

go-check-plugins

開発環境

エディタ

See go --help

See go tool

https://godoc.org/golang.org/x/tools/cmd

参考: http://dominik.honnef.co/posts/2014/12/an_incomplete_list_of_go_tools/

$GOPATH問題

ghq

https://github.com/motemen/ghq

参考

$GOPATH 爆発問題

調子に乗って色々なリポジトリをcloneしてると goimports が重くなる(後述)

goimports

goimports 重くなる問題

雑に幾つか自前スクリプトを書いて凌ぐ

手元でテストを走らせるときに事前に goimports をかける

タスクランナーを充実させる

学習

導入

A Tour of Go やっとけ」で良い

あわせて読みたい

コーディング規約

go tool vet

公式のソースコード検査ツール

% go tool vet -all .

golint

lintツール。golangコア開発者のbradfitz作。

https://github.com/golang/lint

% go get -u github.com/golang/lint/golint
% golint ./...

golintをエラーにしたい

golintをテストする

golintが何らかの出力を出してたらエラーにする。

#/bin/sh
rm -f .golint.txt
golint ./... | tee .golint.txt
test ! -s .golint.txt

マルチプラットフォームで確認したい場合。

#/bin/sh
rm -f .golint.txt
for os in "linux" "darwin" "freebsd" "windows"; do
    GOOS=$os golint ./... | tee -a .golint.txt
done
test ! -s .golint.txt

CIによるチェック

マルチプラットフォーム対応

クロスビルドが簡単とは言うけれど

その幻想をぶち殺す!!

分岐方法

Package build

runtimeによるコード内分岐

ソースコード内のちょっとした分岐に

if runtime.GOOS == "windows" {
    ...
}

ファイル名による分岐

build tagによる分岐

ソースコード内にビルドタグを記述

windowでビルド

// +build windows

windows以外でビルド

// +build !windows

マルチプラットフォーム対応は大変

テスト

標準パッケージで素朴に書く

*_test.go ファイル内の TestXXX という関数がテストケースになる。

pakcage my

import "testing"

func TestHoge(t *testing.T) {
    if false {
        t.Errorf("test failed")
    }
}

これを go test で実行

標準パッケージで大体十分

参考

testify便利

https://github.com/stretchr/testify

CI

カバレッジ測定

coveralls.io連携


gotestcover -covermode=count -coverprofile=.profile.cov -parallelpackages=4 ./...
goveralls -coverprofile=.profile.cov

依存管理

バージョン固定どうするか

Go本体も標準ライブラリも安定している

build and deploy

mackerel-agentの場合

Mackerelの外形監視システムの場合

httpサーバーのhot deploy

リクエストをこぼさないようにする

参考

モニタリング

github.com/fukata/golang-stats-api-handler

サーバーの状態をお手軽にモニタリングできるAPIエンドポイントを作成できる

import (
    "net/http"
    "log"
    "github.com/fukata/golang-stats-api-handler"
)

func main() {
    http.HandleFunc("/api/stats", stats_api.Handler)
    log.Fatal( http.ListenAndServe(":8080", nil) )
}

mackerel-plugin-goserver

golang-stats-api-handlerを利用している場合に簡単にMackerelで可視化可能に。

https://github.com/mackerelio/mackerel-agent-plugins/pull/146

もう少し調整してから公式提供予定。

まとめ

Goでの開発開始から運用に至るまでのノウハウを駆け足でお話しました

We are Hiring

hatena