このページについて
lambda を go で書き、実行途中のtraceをX-Rayに預けるまでの作業が書いてあります(2019/05時点)
開発環境
$ go version
go version go1.12.5 darwin/amd64
手順
関数作成
コンソールからlambdaを作成しましょう
後にX-Rayでlambdaのtrace結果を見たいので下記を有効にしておきます
lambda関数作成後の設定画面にあります
自動的にX-Rayと連携するための権限作成してくれるなんて親切ですね
(必ず画面上部に出る保存ボタン押しとくこと)
lambda を書く
package main
import (
"context"
"fmt"
"io/ioutil"
"github.com/aws/aws-lambda-go/lambda"
)
var (
appName = ""
version = ""
revision = ""
)
type MyEvent struct {
Name string `json:"name"`
}
func HandleRequest(ctx context.Context, evt MyEvent) (string, error) {
return fmt.Sprintf("%s-%s-%s, Hello %s!", appName, version, revision, evt.Name), nil
}
func main() {
lambda.Start(HandleRequest)
}
一応プロダクションを意識しておきたいので、gitのrevisionとか入れてます(loggingは後々ちゃんとやる想定)
build -> deploy -> 実行
Makefileからbuild行います
# if tag doesnt exists, show revision
VERSION=$(shell git describe --tags --abbrev=7 --always)
REVISION=$(shell git rev-parse --short HEAD)
ifeq ($(VERSION),$(REVISION))
VERSION=v0.0.0
endif
NAME=hello
.PHONY: \
init \
build
init:
tfenv install
build:
GO111MODULE=on GOOS=linux go build -v -ldflags "-X main.version=$(VERSION) -X main.revision=$(REVISION) -X main.appName=$(NAME)" -o build/${NAME} *.go
cd build && zip $(NAME).zip $(NAME)
$ make build
できあがった、hello.zipをコンソールからアップロードします
受け取るjsonを修正しておきましょう
下記nameEventのとこから編集できます
↓
そして、実行。。
うん、動いてますねよかった。
X-Ray, CloudWatchで様子を見る
lambda管理画面のモニタリングタブでCloudWatchログ見てみましょう
ざっくりパフォーマンスはわかりますが、lambdaの中で他のサービスにアクセスするとなると
各サービスアクセスの時間が知りたくなったりしますよね?
例えば、s3にアクセスしたあと、あるapiにpost行い、また別のapiにpostするとします
このとき、全体の実行時間はCloudWatchみればわかりますが、どこがボトルネックかはapi側のログと照らし合わせたり
lambdaの中で計測ログを落とす必要があると思います
しかし、そんな面倒なことをせずとも、先ほど設定したX-Rayと連携するようにしてあげれば前述の問題は解決されます
X-Rayのサンプルにあったようにlambdaの中でawsにgetリクエストを送り、その内容をトレースしてみたいと思います。
これを行うとこのようにtrace結果が見れます
さっそくlambdaを書き換えてみます
package main
import (
"context"
"fmt"
"io/ioutil"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-xray-sdk-go/xray"
"golang.org/x/net/context/ctxhttp"
)
var (
appName = ""
version = ""
revision = ""
)
type MyEvent struct {
Name string `json:"name"`
}
func init() {
xray.Configure(xray.Config{
LogLevel: "info",
ServiceVersion: "1.2.3",
})
}
func HandleRequest(ctx context.Context, evt MyEvent) (string, error) {
// Start a segment
ctx, seg := xray.BeginSegment(context.Background(), "api-request")
_, err := getExample(ctx)
if err != nil {
fmt.Println(err)
return "", err
}
// Close the segment
seg.Close(nil)
return fmt.Sprintf("%s-%s-%s, Hello %s!", appName, version, revision, evt.Name), nil
}
func getExample(ctx context.Context) ([]byte, error) {
resp, err := ctxhttp.Get(ctx, xray.Client(nil), "https://aws.amazon.com/")
if err != nil {
return nil, err
}
return ioutil.ReadAll(resp.Body)
}
func main() {
lambda.Start(HandleRequest)
}
$ make build
zipをアップロードして、実行し、成功するはずなのでX-Rayのコンソールで確認してみてください
この次
毎回手動アップロードはしんどいので、terraformなりで構成管理してみようと思います