3
2

More than 5 years have passed since last update.

lambda を go で動かし、X-Rayでtraceするまで

Posted at

このページについて

lambda を go で書き、実行途中のtraceをX-Rayに預けるまでの作業が書いてあります(2019/05時点)

開発環境

$ go version
go version go1.12.5 darwin/amd64

手順

関数作成

コンソールからlambdaを作成しましょう

後にX-Rayでlambdaのtrace結果を見たいので下記を有効にしておきます
lambda関数作成後の設定画面にあります
自動的にX-Rayと連携するための権限作成してくれるなんて親切ですね
(必ず画面上部に出る保存ボタン押しとくこと)
スクリーンショット 2019-05-15 13.32.19.png

lambda を書く

hello.go
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行います

Makefile
# 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のとこから編集できます
スクリーンショット 2019-05-15 19.35.19.png

スクリーンショット 2019-05-15 17.42.57.png

そして、実行。。

スクリーンショット 2019-05-15 17.42.43.png

うん、動いてますねよかった。

X-Ray, CloudWatchで様子を見る

lambda管理画面のモニタリングタブでCloudWatchログ見てみましょう

スクリーンショット 2019-05-15 19.52.32.png

ざっくりパフォーマンスはわかりますが、lambdaの中で他のサービスにアクセスするとなると
各サービスアクセスの時間が知りたくなったりしますよね?
例えば、s3にアクセスしたあと、あるapiにpost行い、また別のapiにpostするとします
このとき、全体の実行時間はCloudWatchみればわかりますが、どこがボトルネックかはapi側のログと照らし合わせたり
lambdaの中で計測ログを落とす必要があると思います

しかし、そんな面倒なことをせずとも、先ほど設定したX-Rayと連携するようにしてあげれば前述の問題は解決されます

X-Rayのサンプルにあったようにlambdaの中でawsにgetリクエストを送り、その内容をトレースしてみたいと思います。
これを行うとこのようにtrace結果が見れます

スクリーンショット 2019-05-15 20.00.31.png

スクリーンショット 2019-05-15 20.01.17.png

さっそくlambdaを書き換えてみます

hello.go
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のコンソールで確認してみてください

スクリーンショット 2019-05-15 20.06.08.png

この次

毎回手動アップロードはしんどいので、terraformなりで構成管理してみようと思います

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2