Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

最初に知っておけば良かったFilebeatの設定

こんにちは。

最近、Filebeatによるログ収集について興味を持ちつつ、
いろいろと調べながら使っているsawaです。

この記事は、Elastic stack (Elasticsearch) Advent Calendar 2018 - Qiitaの、13日目の記事になります。

はじめに

Elastic Stackを使ったログ収集を行うには、
Logstashを使う、Beatsシリーズを使うといった、選択肢があります。

本記事では、Filebeatを使う際に知っておくと良い設定を紹介したいと思います。

Filebeatとは?

f:id:acro-engineer:20181212180846j:plain

Filebeatには次のような特徴があります。

  1. データ収集ツールとして、軽量に扱える。
  2. 用途が限定されているため、シンプルに使える。
  3. ミドルウェアに応じたプラグインを適用することで、自動でダッシュボードの生成までも行える。

詳細についてはドキュメントに記載があります。
www.elastic.co

大量のログファイルを収集する際に陥りがちな問題

手元にある大量のファイルをElasticsearchにインデクシングする必要があり、Filebeatを使いました。
ひとまずFilebeatをデフォルト設定のまま使ったところ、うまく収集できず、Filebeatのログにこんな出力がされました。

A:

Harvester could not be started on new file: /var/log/foo_xxxx.log, 
Err: error setting up harvester: Harvester setup failed. Unexpected file opening error: 
Failed opening /var/log/foo_xxxx.log: open /var/log/foo_xxxx.log: too many open files

B:

Failed to connect to backoff(elasticsearch(http://localhost:9200)): Get http://localhost:9200: 
dial tcp [::1]:9200: socket: too many open files

Aはログファイルを開けない事象、BはElasticsearchへの接続が行えない事象を指しています。

例えば、3,000個のログファイルを読み込んでしばらくすると、オープンファイル数が1,000近くになることがFilebeatのログから分かりました。
それにより、OSのファイルディスクリプタのソフトリミットである1,024近くになっていたことが分かりました。
ファイルディスクリプタを使う数を減らしたいですね。

Filebeatにおける収集の仕組みと対策

対策するために、まず、Filebeatによる収集の仕組みを押さえます。

収集の仕組み

Filebeatは、以下の流れでログを収集します。

f:id:acro-engineer:20181213103928j:plain

①収集対象ファイルの一覧取得
 デフォルト10秒間隔で、タイムスタンプが新しいファイルを収集対象に入れます。
 (一覧取得間隔はfilebeat.ymlの「scan_frequency」で変更可能)
 一覧に入ったファイルは、②で収集開始します。

②収集の開始(ファイルハンドラの確保)
 1ログファイルにつき1つずつのファイル収集のためのインスタンスが立ち上がります。
 これを「ハーベスタ」といいます。

③更新の検知と送信
 デフォルト1秒間隔で、新しい行が追加されていれば差分を外部に送信します。
 (更新の検知間隔はfilebeat.ymlの「backoff」で変更可能)

④収集の終了(ファイルハンドラの解放)
 filebeat.ymlで定義された条件を満たすと、ハーベスタによる収集が終了します。


上記の④で収集を終了(ファイルハンドラを解放する)条件の設定は以下のドキュメントで紹介されています。
 Log input | Filebeat Reference [6.5] | Elastic

  • 一定時間以上の更新が無い場合(filebeat.ymlの「close_inactive」で変更可能)
  • ファイルが削除された場合
  • ファイルがリネームされた場合
  • ファイルがEOFに達した場合
  • ファイルハンドラを作って一定時間が経過したら強制的に解放

これら設定は、ユースケースに応じて柔軟にカスタマイズが必要ですね。
Filebeatを利用する前にチェックしてみてください。

今回の場合は5分以上更新が無いログファイルなので、「一定時間以上の更新が無い場合」(close_inactive)の時間を短縮することでファイルディスクリプタの枯渇によるエラーの発生を抑えることができそうです。
(もちろん、OSの設定を変更するという手段もあります)

以下の条件を満たすログを収集する場合は、close_inactiveの短縮が有効と言えるでしょう。

  • 更新頻度がさほど少ない
  • サイズが小さめ
  • 1,000以上ある大量の数のログが収集対象

「close_inactive」による対策

「close_inactive」を具体的に紹介します。
デフォルトは5m(5分間)で、単位に分(m)や秒(s)を指定可能です。

短くすることでより早くファイルハンドラが解放されるようになります。
ファイルハンドラが解放されることで、待ち状態の次のファイルが次々と読み込まれていきます。

ただし、短くし過ぎると、次に更新が掛かった後にファイルハンドラを再取得するまでのタイムラグが生じます。
(①で説明したscan_frequency分待つ必要があります)

今回の検証では、1mに短縮してみます。

  close_inactive: 1m

今回はこれで解決できました。
この設定を先に知っておけば良かったですね。

最後に

Filebeatを使うために知っておけば良かった設定について紹介しました。
Filebeatを使う際に、こんな設定あったなと、思い出して、このページを見て頂ければ幸いです。

それではまた。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
ユーザに最高の検索体験を提供したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

LambdaからRekognitionを使ってみたら意外なところでハマった話

本エントリは、AWS #2 Advent Calendar 2018の12日目です。

こんにちは! 気付けばAcroquestに入社してもう10年目、最近はAWSを使った開発やDevOpsの活動に携わっているiidaです。

今回は、少し前に上司から「Amazon Rekognition Imageを使うことになるかも知れない」と言われて触ってみたら、意外なところで嵌った話をしたいと思います。

AWS Rekognitonとは

人工知能機械学習に基づく画像認識・画像分析サービスです。こう書くと何やら難しそうですが、百聞は一見にしかず、AWSコンソールのデモを見てみましょう。

f:id:acro-engineer:20181209232237p:plain:w800

これは「オブジェクトとシーンの検出」で、画像中にどんなオブジェクト(CarやPersonなど)があるのか、あるいはどんなシーン(TransportationやSportsなど)なのかを検出し、その位置まで教えてくれるようです。

私は機械学習についてはほとんど知識がありませんが、それでもこのようは画像解析ができるようになるなんて、すごい世の中になったものですね!

Pythonから呼んでみる

さてさて、このようなサービスがあるということは分かりましたが、エンジニアとしてはやはり自分の書いたコードから使ってみたいものですよね!

ということで、早速PythonからRekognitionを呼び出すコードを書いてみました。

import json
import boto3

# ローカルの画像ファイルを読み込む。
with open('sample.jpeg', 'rb') as image_file:
    image_bytes = image_file.read()
# Rekognitionのラベル検出を呼び出す。
rekognition = boto3.client('rekognition', 'ap-northeast-1')
response = rekognition.detect_labels(Image={'Bytes': image_bytes})
print(json.dumps(response, indent=2))

たったこれだけ。簡単!

f:id:acro-engineer:20181209231438j:plain:w600

試しにこの画像を解析してみましょう。先日のHappy360(全体査定)の時の一コマです。どんなレスポンスが返って来たのかというと…。

{
  "Labels": [
    {
      "Name": "Human",
      "Confidence": 99.71063232421875,
      "Instances": [],
      "Parents": []
    },
    {
      "Name": "Person",
      "Confidence": 99.71063232421875,
      "Instances": [
        {
          "BoundingBox": {
            "Width": 0.31008321046829224,
            "Height": 0.6783191561698914,
            "Left": 0.626418948173523,
            "Top": 0.31440863013267517
          },
          "Confidence": 99.71063232421875
        },
            :(以下省略)

なるほど、Nameがオブジェクトやシーンの種類で、BoundingBoxが画像中の位置のようです。HumanとPersonの違いがよく分かりませんが、Humanは「人が写っている」ということを表しているのでしょうか?

結果を画像に描画してみる

これだけだと分かりづらいので、デモみたいにラベルを画像に描画してみましょう。

import cv2

# (ここに先ほどのコードが入ります。)

# CV2で画像ファイルを読み込む。
np_image = cv2.imread('sample.jpeg')
height, width = np_image.shape[:2]

# ラベルの中から人と思われるものを探して四角で囲う。
for label in response['Labels']:
    if label['Name'] not in ['People', 'Person', 'Human']:
        continue

    for person in label['Instances']:
        box = person['BoundingBox']
        x = round(width * box['Left'])
        y = round(height * box['Top'])
        w = round(width * box['Width'])
        h = round(height * box['Height'])
        cv2.rectangle(np_image, (x, y), (x + w, y + h), (255, 255, 255), 3)
        cv2.putText(np_image, label['Name'], (x, y - 9),
                    cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 3)

cv2.imwrite('./sample_result.jpeg', np_image)

BoundingBoxの値は、画像の幅と高さに対する割合となっているので、少し計算が必要です。これを実行してみると…。

f:id:acro-engineer:20181209231555j:plain:w600

Great! 手前の2人だけでなく、奥にひっそりといる人もちゃんと検出されていますね!

Lambdaから実行してみる

ここまで来たら、Lambda上でも動かしてみたくなりますよね!(えっ、ならないですか?)

S3にアップロードされた画像ファイルを自動で解析するLambda関数を書いてみました。

import os

import boto3
import cv2

s3 = boto3.resource('s3')


def handle_request(event, content):

    # S3にアップされた画像の情報を取得する。
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    object_key = event['Records'][0]['s3']['object']['key']
    file_name = os.path.basename(object_key)

    # 画像をRekognitionで解析する。
    rekognition = boto3.client('rekognition')
    response = rekognition.detect_labels(Image={
        'S3Object': {
            'Bucket': bucket_name,
            'Name': object_key
        }
    })

    # S3から画像をダウンロードする。
    tmp_dir = os.getenv('TMP_DIR', '/tmp/')
    bucket = s3.Bucket(bucket_name)
    bucket.download_file(object_key, tmp_dir + file_name)

    # 検出した人物に枠を描画する。
    image = cv2.imread(tmp_dir + file_name)
    height, width = image.shape[:2]

    for label in response['Labels']:
        if label['Name'] not in ['People', 'Person', 'Human']:
            continue

        for person in label['Instances']:
            box = person['BoundingBox']
            x = round(width * box['Left'])
            y = round(height * box['Top'])
            w = round(width * box['Width'])
            h = round(height * box['Height'])
            cv2.rectangle(image, (x, y), (x + w, y + h), (255, 255, 255), 3)
            cv2.putText(image, label['Name'], (x, y - 4),
                        cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 3)

    cv2.imwrite(tmp_dir + file_name, image)

    # S3に描画後の画像をアップロードする。
    bucket.upload_file(tmp_dir + file_name, 'result/' + file_name)
    os.remove(tmp_dir + file_name)

ちなみに、CV2(opencv-python)は非Pure Pythonなので、Amazon Linux上でビルドまたはpip installしたものをデプロイパッケージに含めるか、Serverless Framworkを使用する場合はServerless Python RequirementsプラグインでdockerizePipを有効にする必要があります(ここでも少し嵌った)。

デプロイパッケージが50MB近くになってしまいましたが、無事デプロイが完了したので、早速S3バケットに画像ファイルをアップロードしてみます。すると…。

'Instances': KeyError
Traceback (most recent call last):
  File "/var/task/person_detector.py", line 44, in handle_request
    for person in label['Instances']:
KeyError: 'Instances'

あれ? ラベルにInstancesが無いって怒られてしまいました。ローカルで動かした時にはこんなエラーは出なかったのですが、そんなこともあるんですかね?

        if label['Name'] not in ['People', 'Person', 'Human'] or 'Instances' not in label:
            continue

突貫ですが、処理するラベルの条件式をこんな風に変えてみました。

f:id:acro-engineer:20181209231438j:plain:w600

すると、出力フォルダに画像はできたのですが、ローカルでは描画されていたラベルがありません。何故だ?!

    response = rekognition.detect_labels(Image={'Bytes': image_bytes})
    print(json.dumps(response, indent=2))

こうなったらログ出力しかありません。Rekognitionからのレスポンスを表示してみると…。

{
  "Labels": [
    {
      "Name": "Person",
      "Confidence": 99.57161712646484
    },
    {
      "Name": "Human",
      "Confidence": 99.57161712646484
    },
        :(以下省略)

なんと、ローカルで実行した時よりも取得できる情報が少ないではありませんか!

こんなことが起こり得るのかと思って調べてみたところ、どうやら古いバージョンのBoto3だとこれらの情報しか取得できないようです。あれ、そう言えばLambdaではデフォルトでBoto3が使えますが、あれってもしかして…。

f:id:acro-engineer:20181209231248j:plain:w600

これだ!

確かに言われてみれば当たり前ですが、今まで意識したことがなかったので盲点でした。バージョンによって関数の有無があるのは想像できますが、レスポンスが異なるなんてこともあるんですね。

f:id:acro-engineer:20181209231555j:plain:w600

その後、最新のboto3とbotocore、そしてurllib3もデプロイパッケージに含めたところ、ローカルと同じくラベルの描画された画像が出力されました。(デプロイパッケージが50MBを超えてしまいましたが。。)

Amazon Rekognitionだけでなく、普段使っているAWS Lambdaについても理解を深められ、とても良い勉強になったと思います。LambdaからRekognitionを使おうと思っている方はお気を付け下さい! 以上、AWS #2 Advent Calendar 2018の12日目でした!

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
ユーザに最高の検索体験を提供したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

Vega利用時によくある7つの疑問

こんにちは、今年7月にElastic Certified Engineer認定を取得したHiroshi Yoshioka です。

この記事は Elastic stack (Elasticsearch) Advent Calendar 2018 の11日目の記事になります。

はじめに

今日のお題はVegaです。
VegaはKibanaの可視化の幅を拡大する優れたフレームワークなのですが、Elastic公式ドキュメントに情報が少ないため、取っつきやすいとは言えません。

そこで本記事では、Vegaを利用時によくある7つの疑問について回答します。 ※Vega-Liteについては扱いませんのでご了承ください。

1. そもそもVegaって何者?

VegaはインタラクティブなVisualizationを作成するための宣言型Web言語。
JSONCSVを読み込み、様々なチャートを可視化することができます。

Vega公式ページにあるサンプルを見るとすぐに分かりますが、表現できるVisualizationの種類が非常に豊富です。

例えば、このチャートを開いてみてください。
一見普通の散布図に見えますが、丸いシンボルをドラッグすると、時間軸を変更することができる!

Vegaを利用すると、このようなインタラクティブな表現をKibanaで実現できるのです。 vega.github.io

2. KibanaとVegaの関係は?

Kibana Ver.6.2.0からVisualizeにVegaを利用できるようになりました。
Vegaで作成したチャートは、Visualizeとして保存したりDashboardへ配置することが可能です。
※Ver.6.2.0以前のKibanaでVegaを利用するには、別途プラグインのインストールが必要になります。

3. 手取り早くKibana上で動くVegaを見るには?

Kibana 6.4.0以降、ワンクリックで可視化可能なサンプルデータが付属しており、VegaのVisualizeも含まれています。
こちらを利用しましょう。(本記事では6.5.0を使用します。)

まず以下をセットアップ。サンプルデータ投入画面を開きます。

  • Elasticsearch 6.5.0
  • Kibana 6.5.0

f:id:acro-engineer:20181211010713p:plain
サンプルデータ投入画面

Sample flight dataの「Add」をクリックして、航空データを投入します。

f:id:acro-engineer:20181211011120p:plain
サンプルデータ投入画面

View dataをクリックしてDashboardをオープン。

f:id:acro-engineer:20181211011233p:plain
航空データダッシュボード

右下にVegaで作られたVisualize(世界地図)があるのでEdit Visualizationを選択。 世界地図にプロットされた空港にマウスカーソルを合わせると、フライト情報のPathとツールチップが表示されます。

f:id:acro-engineer:20181211011658p:plain
航空データのVega Visualize

4. Vegaの公式ページのサンプルがKibanaで動作しないのはなぜ?

Vegaの公式ページには、Vega最新バージョンに関するドキュメントが公開されています。
2018/12/11時点では、Vegaの最新は4.4.0。一方で、Kibana 6.5.0に組み込まれているのはVega 3.3.1です。
だいぶ、バージョンに開きがありますね。

公式ページには、Vega 4.Xで追加された機能を用いたサンプルも公開されていますが、当然ながら、Vega 3.3.1が組み込まれたKibanaでは動作しません。

5. Kibanaに組み込まれたVegaのバージョンを確認する方法は?

ChromeでVegaのVisualize画面を表示し、デベロッパーツールを開きます。続いて、Console画面で以下のコマンドを実行してください。

VEGA_DEBUG

Vegaは3.3.1、Vega-Liteは2.4.0が組み込まれていることが分かります。

f:id:acro-engineer:20181211012945p:plain
Kibanaに組み込まれたVegaのバージョンを確認する

6. ダッシュボードでVegaを操作してダッシュボード全体にフィルタをかける方法は?

ダッシュボードに配置された通常のVisualizeは、クリックすることでContents Filterを作成し、ダッシュボード全体にフィルタをかけることができます。
Vegaの場合も同様にフィルタをかける方法はあるのでしょうか。

はい、あります。

公式ドキュメントには書かれていませんが、Kibana 6.4.0以降ではVegaからContents Filterの追加/削除を行う機能(関数)が組み込まれています。

# ダッシュボードにContents Filterを追加する
# query    :フィルタ内容
# index-pattern  :フィルタするインデックスパターン名
kibanaAddFilter( <query>, <index-pattern>)

先ほど開いた、航空データのVega Visualizeにフィルタ機能を追加してみましょう。

Vegaコードを開き、signals配下に以下を追加して保存します。

    {
      name: filter
      on: [
        {
          events: @airport:click 
          update: '''
            kibanaAddFilter({
                      match: {
                      OriginAirportID : {
                        query: datum.key,
                        type: 'phrase'
                    }}},'kibana_sample_data_flights')
          '''
        }
      ]
    }

f:id:acro-engineer:20181211015802p:plain
Vegaにフィルタ機能を追加

航空データダッシュボードを開いてフィルタ機能を確認してみましょう。
フィルタを実行する前です。データは298件。

f:id:acro-engineer:20181211020053p:plain
Vegaにフィルタ機能を追加したダッシュボード

地図上の適当なシンボルにカーソルを合わせて、クリック。

f:id:acro-engineer:20181211020152p:plain
Vegaにフィルタ機能を追加したダッシュボード

何やら、他のVisualizeの様子が変わりました。

f:id:acro-engineer:20181211020222p:plain
Vegaにフィルタ機能を追加したダッシュボード

ダッシュボード上部をみてみると、Contents Filterが追加されてデータが5件に絞り込まれていることが分かります。

f:id:acro-engineer:20181211020248p:plain
Vegaにフィルタ機能を追加したダッシュボード

他にも、指定したフィルタを解除する関数や、

kibanaRemoveFilter( <query>, <index-pattern>)

全てのフィルタを解除する関数。

kibanaRemoveAllFilters()

TimePickerを操作する関数も用意されています。

kibanaSetTimeFilter(<start>, <end>) 

7. Vegaをデバッグするには?

Vegaのデバッグデベロッパーツールにて「VEGA_DEBUG」オブジェクトを介して行います。 代表的なコマンドを紹介します。

dataの内容を表示する

# valuesの内容を表示
VEGA_DEBUG.view.data('values')

dataの内容をテーブル表示する

# valuesの内容をテーブル表示
console.table(VEGA_DEBUG.view.data('values'))

signalの値を取得する

# heightの値を取得
VEGA_DEBUG.view.signal('height')

signalの内容を任意の値に変更して実行する

# heightの値を100変更
VEGA_DEBUG.view.signal('height',100).run();

scaleの内容を表示する

# scale yの内容を表示
VEGA_DEBUG.view._runtime.scales.y

最後に

本記事ではVega利用におけるよくある7つの疑問に回答しました。 あとは文法を覚えれば(これが大変なのですが)、Vegaを自在に扱うことができるはずです。

Let's enjoy vega life !





Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

ユーザに最高の検索体験を提供したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

Serverless Frameworkで AWS Lambda Layers を試してみる

こんにちは、最近のクラウドシステム開発は、ほぼサーバーレス・アーキテクチャで対応している takanorig です。
この記事は Serverless Advent Calendar 2018 の9日目の記事です。

昨日は、システムテスト自動化カンファレンス2018で、「マイクロサービスのテスト自動化 with Karate」という内容で発表をしてました。
上記はテスト自動化に関する内容ですが、こちらも、サーバーレス・アーキテクチャの関連があって利用を始めたもの。
当初、このKarateを使っての内容を書こうかと思っていたのですが、今回のタイトルの内容の方が自分的に優先度が高くなったので、内容を切り替えての投稿です。

f:id:acro-engineer:20181210075313j:plain

はじめに

先日のre:Invent2018で AWS Lambda Layers が発表されましたが、「これはPJで早速導入したい」と思った内容でした。
社内のプロジェクトでは、主にServerless Frameworkを使ってServerlessなサービスの開発を行っているのですが、Lambda Layers を使えるのかな?と思って確認したところ、Serverless Frameworkでも既に対応されていました!(対応が早い)。

ということで、本エントリーでは、Serverless Frameworkで、AWS Lambda Layers を試してみます。

※今回の内容は、AWS Lambda/Serverless Framework 自体の基本的な知識は有していることを前提にしています。

AWS Lambda Layers とは?

既にご存知の方も多いかもしれませんが、簡単に、どういうものか説明しておきます。

従来のLambdaでは、共通モジュール(共通で利用するファンクションやライブラリなど)がある場合に、それを利用する各ファンクションと合わせて、それぞれごとにパッケージングしてデプロイすることが必要でした。その分、パッケージのサイズが肥大化したり、その分デプロイに時間がかかってしまう、という課題がありました。

Lambdaでも、それなりの規模の開発になってくると、当然、共通モジュールなども増えてきますよね。

これに対して、Lambda Layers を使うことで、上記のような課題を解決できる状況になりました。Lambda Layers は、共通モジュールをひとつのzipファイルにまとめてアップロードし、各ファンクションから呼び出すことができるようになります。

Serverless Framework での Lambda Layers の利用

公式サイトの情報として、以下が参考になります。

環境

今回は、以下のような環境で確認をしています。
Layersの機能を利用するためには、Serverless Frameworkは、1.34.0以上であることが必要です。

環境 バージョン
Mac macOS Mojave 10.14.1
node 10.14.1
npm 6.4.1
Serverless Framework 1.34.1
言語 Python 3.6.0

前準備

今回、Pandasを利用した処理を試してみます。
そのためには、予め Amazon Linux 環境でビルドしたファイルを用意する必要があります。

まず、Pandasをビルドするに、ディレクトリ構成を以下のようにしています。

sls-layers-example
  └── layers
      └── pandas
          ├── package.sh
          └── requirements.txt

それぞれのファイルの中身は、以下のようになります。

  • package.sh
#!/bin/sh

export OUTPUT_DIR="python"

rm -rf ${OUTPUT_DIR} && mkdir -p ${OUTPUT_DIR}

docker run --rm -v $(pwd):/var/task -w /var/task lambci/lambda:build-python3.6 \
    pip install -r requirements.txt -t ${OUTPUT_DIR} 

ここでは、簡単に Amazon Linux の環境でビルドできるように、 lambci/docker-lambda を利用しています。
これを使うと、Dockerを利用してビルドができますね。

  • requirements.txt
pandas==0.23.4

上記の準備ができたら、Pandasのビルドを行います。

$ cd /{path}/sls-layers-example
$ cd layers/pandas
$ ./package.sh
Collecting pandas==0.23.4 (from -r requirements.txt (line 1))
・・・
Installing collected packages: six, python-dateutil, pytz, numpy, pandas
Successfully installed numpy-1.15.4 pandas-0.23.4 python-dateutil-2.7.5 pytz-2018.7 six-1.11.0

上記のように、ビルドが成功すればOKです。

serverless.yml / Lambda関数 の作成

先ほどのディレクトリ構成に対して、以下のように serverless.ymlanalysis_lambda.py を追加します。

sls-layers-example
  ├── analysis_lambda.py
  ├── layers
  │   └── pandas
  │       ├── package.sh
  │       └── requirements.txt
  └── serverless.yml
  • serverless.yml
service: sls-layers-example

frameworkVersion: ">=1.34.0 <2.0.0"

provider:
  name: aws
  runtime: python3.6
  stage: dev
  region: us-west-2

package:
  individually: true

# AWS Lambda Layers
layers:
  pandas:
    path: layers/pandas
    name: ${self:service}-pandas
    compatibleRuntimes:
      - python3.6
    allowedAccounts:
      - '*'

# AWS Lambda Functions
functions:
  analyze:
    handler: analysis_lambda.analyze
    layers:
      - {Ref: PandasLambdaLayer}
#     - arn:aws:lambda:${self:provider.region}:xxxxxxxxxxx:layer:{service名}-{layer名}:{バージョン}

既に登録されているLayerを使う場合は、ARNの形式で指定する必要がありますが、同じserverless.ymlで参照する場合は、「PandasLambdaLayer」(Layerに応じてCloudFormationで名前が設定される)のような名称で参照ができます。

  • analysis_lambda.py
# -*- coding: utf-8 -*-
import pandas as pd

def analyze(event, context):
    names = ['Bob','Jessica','Mary','John','Mel']
    births = [968, 155, 77, 578, 973]

    BabyDataSet = list(zip(names,births))

    df = pd.DataFrame(data = BabyDataSet, columns=['Names', 'Births'])
    print(df)

ここでは簡単に、配列から、DataFrameを利用して、データセットを作成しています。

デプロイ

ここまでくれば、あとはデプロイするだけです。

$ cd /{path}/sls-layers-example
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (609 B)...
Serverless: Uploading service .zip file to S3 (32.64 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
・・・・

Pandasのライブラリの部分は、32.64MBありますね。
それなりのサイズになっています。

デプロイ結果確認

AWSコンソールにログインして、デプロイ結果を見てみましょう。
以下のように、キチンと「Layer」に登録されており、Lambda関数からも参照できているようです。

f:id:acro-engineer:20181210071340p:plain
Layers

ビルドしたPandasが、Layerとして登録されています。

f:id:acro-engineer:20181210071407p:plain
Function

Layerに登録されたPandasが、「参照されるレイヤー」の部分で確認できます。

テスト

デプロイされたLambdaをテストしてみます。

f:id:acro-engineer:20181210071527p:plain
Test

f:id:acro-engineer:20181210071550p:plain
Result

AWSコンソールの機能で、テストを実行してみたところ、きちんと実行ができたようです!

注意点

Layersを使う場合の制限は、予め把握した上で利用する必要があります。
特に注意すべき点は、以下の内容でしょう。

  • Layerは、5つまで。
  • デプロイ可能なサイズは、圧縮したサイズ:50 MB/解凍した際にLayerも含めたサイズ:250 MB

詳細は、以下から確認ができます。

まとめ

ServerlesFrameworkから、AWS Lambda Layers を使ってみました。

これで、各関数で共通的に必要となる共通モジュールの管理が、より整理でき、効率的な開発ができそうです。
また、Layersでは、バージョンごとに保存されるようにもなっているので、複数の関数で、同時に変更ができないような場合でも対応できそうです。



Acroquest Technologyでは、キャリア採用を行っています。

【特別対談】 ITベンチャーが語る #エンジニアリング組織論 とは に参加してきました!

皆さん、こんにちは。村田です。
私はプロダクトマネージャー兼エンジニアリングマネージャーの立場で仕事をしているのですが、そんな私にとって非常に興味深いタイトルのイベントがあり、参加してきました。

lob.connpass.com

イベントに参加した経緯

書籍「エンジニアリング組織論への招待」を読んだ方は多いと思います。私も読んですぐに社内のメンバにも「これは必読!」と勧めた口なのですが、その著者の広木さんがトークセッションに出る、さらに個人的にファンであるJapan Node.js Associationの代表理事である古川さんも出るとあって、申し込みました。

イベントの形式

イベント全体としては、イベントを主催しているLOBさんBizteXさんの会社紹介があった後、LOB CEOの竹林さんをモデレータとして、

  • エンジニアリング組織論への招待の著者 広木さん
  • Japan Node.js Association 代表理事 古川さん
  • BizteX CTO 袖山さん
  • LOB CTO 中原さん

というメンバで、ITベンチャーが各テーマについて取り組みを話し、広木さん、古川さんからのコメントが語られるという形式で進み、最後に質疑応答+懇親会という形式でした。

f:id:acro-engineer:20181201214309j:plain

この記事では参加レポートとして、印象に残った内容とそこで思ったことをテーマ別にまとめています。
*1

Theme01 初期採用

基本はリファラル採用に両社とも力を入れたという話でした。

LOBさんの話で、最初は2名でとにかくずっとやっていて、掲げるミッションを言語化できてから採用に力を入れ、人も集まるようになったという話、BizteXさんも事業戦略からマネジメント方針のロジックを作ることを大切にしていると話されていて、やはりミッションとかバリューの言語化が重要だよなぁと感じました。


 うちの社内でもミッション、社員理念、バリューとかを社員みんなで話して細かい文言にもこだわって決めています。
 なので、他社のミッションとかバリューがどのような内容なのか、どんな意味が込められているのかはとても興味があります。


会社紹介の中で、LOBさんのバリューとして紹介された「(Put Your)Hands Up ~名乗りを上げよう~」、BitteXさんのマネジメントの2本柱の1つとして紹介された「個人の利と会社の利を合わせる」という文言は素敵だと思いました。


リファラル採用って実際にどうやっているのだろう?と私も思ったのですが、採用での口説き文句があれば教えてほしいという質問の中で、
広木さんから

「あなたと一緒に働きたい」というメッセージをちゃんと伝えているか?

というコメントが心に残りました。単に人手が足りなくてエンジニアが必要だ、とだけ伝えていないかという点は今後に活かしたいです。

Theme02 チーム開発

「新しい技術を導入したいというメンバがいたとき実際にどうしているか?」という問いについて古川さんが、

実際的にはただその技術を使うというだけでなく、チーム開発しているので、他の人もできるようにする仕組み作りや教育などまで含めて必要になることを説明することが必要。やるべきことは多いのだが、それでも(それも含めて)やりたいか?とちゃんと聞く

ということを言われていて、とても賛同しました。

そこに広木さんの「やりたいと言わせたら勝ち」、「失敗できることは福利厚生」というキャッチーな言葉が紹介されましたが、それはつまり、そのような状況や環境作りがエンジニアリングマネージャーの役割だよ、ということだと理解しました。

Theme03 目標設計/評価制度

評価制度

評価制度は本来的にはなくてもよいものなので、評価制度とはわざわざ作るもの
では何故わざわざ作るのかと言えば、それは「納得」と「成長」のため

といういきなり本質的な広木さんのコメントがありましたが、これは非常によくわかる話でした。


 というのも、うちの会社では全社員が査定会に参加し、全社員で給与を決定する仕組みである「Happy査定360」というシステムをやっています。
 これをなぜやっているか、と一言でいえば、「納得と成長のため」です。


 よく「全社員で給与を決定する」という所に驚かれて、その点を聞かれることが多いのですが、大事なことは、給与は最終的な結果であり、
 そこに至る評価の部分を皆で議論を尽くしてやっていることだと思っています。評価軸や職位に求められる責務、会社として必要なスキルや
 目指すべき理想について話すことで納得を高め、成長につなげるように意識しています。


評価の部分は、最初に出てきた会社のミッションやバリューと合わさって組織を設計する重要な要素だという思いをより強く持ちました。

目標設計

主に広木さんから次のようにコメントがありました。

目標設計は評価制度に結びつけ過ぎないようにする。それは何故か?
評価に直結すると、次第に目標が達成できるレベルに下がってしまうから。

目標は120%頑張ったら達成できるくらいの高いものにして、

  • 目標が100%達成できたらすごい
  • 70%ぐらいの達成で合格

くらいでないと、モチベーションも上がらないでしょ?という内容だったと記憶しています。

この目標設計とそのマネジメントに関しては、自分自身もモヤモヤとしている所があるので、今回の話やOKRなどをもう少し学んで、2019年は組織として目標設計をもっと効果的に仕組み化できるようにしたいとモチベートされました。

Theme05 マネジメント

エンジニアリングマネージャの重要性/役割について、どんな人が向いているかなどが話されました。

古川さん自身がエンジニア(エキスパート)とマネージャーの両方の役割をやられていて、

それぞれに面白さがあり、どちらか片方しかやってはいけないということではない。
両方をどちらも楽しんでやれているというロールモデルとなりたい

と話されていて素敵でした。業界としてそのようなエンジニアリングマネージャーが増えるとよいですよね。私自身もそうありたいです。

広木さんからは

マネージャはあくまでもロールであり、神様でも親でもない、
皆同じ人間であり、相互のやりとりは人間通しの関わり合いであること、大人であること、成熟さが必要

という話がありました。

完璧な人なんていないので、人それぞれ得意不得意があって、それをオープンに共有できる組織でありたいと思っています。
個人的にはこのエンジニアリングマネージャーという役割を、何も一人ですべてをやりきるというのではなく、エンジニアリングマネージャーチームという形で捉えてもよいなぁなどと考えました。

おわりに

通常の技術的なイベントではなく、こうした組織論のイベントに参加するのは初めてでしたし、広木さんや古川さん、そして、実際にITベンチャーであるLOBさん、BizteXさんの生の話を聞きながら自分の会社の取り組みを振り返ることは非常に貴重な機会となりました。

主催してくださったLOBさん、BizteXさん、ありがとうございました。
私も機会があればこのような場で話ができるようにしていきたいです!

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
ユーザに最高の検索体験を提供したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

*1:LOBさん、BizteXさんの会社紹介、トークセッション、質疑応答部での内容もすべて含めてまとめていますので、時系列順ではありません。 また、内容は私が理解したことをなるべく間違いがないように記載しましたが、もしご指摘等ありましたら、お知らせください。

KibanaのVisualizeでExcelっぽい表現をする

はじめまして、kareyamaです🍂

アップデートの度にオシャレなグラフが増えるKibanaのVisualizeですが、Excelに慣れ親しんだ日本人にはシンプルな表形式がウケるようで。
Data Tableに対して「全体に対する割合を見たい」「異常値を強調表示してほしい」などの要望が出て困っていました。

そんな時、弊社のElastic認定エンジニアの言葉が耳に入ってきました。
「Visual BuilderのTableで、Dashboardの一覧を…」

…Visual BuilderのTable??
さっそくElasticsearchのバージョンを上げて確認します。どうやら6.3からExperimentalとして追加されたようです。

見た目はこんな感じ。
f:id:acro-engineer:20180930020902p:plain

Data Tableとの比較

結論から言ってしまうと、Data tableに対し、Visual Builder Tableは以下の事ができました。

  1. aggregateの結果を変数として、スクリプトが使える ⇒ 四則演算できる
  2. 列単位でフィルタをかけられる
  3. 簡単な条件付書式が使える

逆に、Data tableと違い、以下の制約があります。

  1. Data tableはsplit rowを複数、かつAggregationを選んで指定できるが、Visual Builder Tableでは、行の数は単一のterms aggregationで決まる
  2. Data tableがTime Pickerで指定した期間のデータがテーブル化するのに対し、Visual Builder TableはTime Pickerで指定した期間を「interval」でBucketに分割した上で、 最後(最新)のBucketに含まれるデータのみをテーブル化する

実装

では、実際に使ってみます。
今回は気象データの「日照時間」と「天気」を使い、スクリプトで計算した日照率と、特定の天気の日数を都市ごとに表示します。

気象庁から北海道・大阪・沖縄の気象データを1月分取得し、logstashで取り込みました。
f:id:acro-engineer:20180930084011p:plain

VisualizeからTime Series Visual Builderを選択します。
f:id:acro-engineer:20180930022419p:plain


画面上部のリンクから「Table」を選択。

「Columns」タブの「Group By Field」にlocationフィールドを選択します。
f:id:acro-engineer:20181103124238p:plain


「panel option」を開き、index patternとintervalを設定します。
今回はデータ全体を見たいので、Bucketに分割されないようintervalを大きめに設定します。

ここで、time pickerよりintervalを長く設定して、31d、32d、33d、と試してみると、
値によって結果が変わるのはなぜか、よくわかりませんでした。
f:id:acro-engineer:20181104150204j:plain

「50d」で設定すると、全データが表示されたので、これで進みます。
f:id:acro-engineer:20181103124410p:plain

四則演算

まずは、各都市の平均日照時間を表示します。
これはUIが異なるだけで従来のData Tableと同じですね。
f:id:acro-engineer:20180930095204p:plain

f:id:acro-engineer:20180930095222p:plain

これだとお日様がどれくらい仕事してるかよく分からないので、日照率を計算してみます。

この月、日の出は大体5:30、日の入りが18:30だったようなので、13時間で割りましょう。
こんな感じのMetrics定義になります。
f:id:acro-engineer:20180930100452p:plain

Visuaizeはこんな感じに。
f:id:acro-engineer:20180930100732p:plain
ちゃんと計算できていますね(^o^ 三 ^o^)
今回はサンプルとして可照時間を固定値にしましたが、日の出・日の入り時刻のデータを入れれば日ごとに算出する事も可能ですね!

書式変更

単位の表示がなく、閲覧者からは数値の意味がわかりにくいです。
そのため、まず日照率は「%」を付けましょう。

また、異常に低い値と高い値に注目してもらうため、目立たせたいです。
日照率が30%を切っている場合は文字を青く、70%を超えている場合赤くします。
f:id:acro-engineer:20180930100520p:plain

f:id:acro-engineer:20180930100541p:plain

北海道はずいぶん天気が悪かったようです。
では、どれくらいの日数、曇りか雨だったのでしょう?
実際の数字を出してみようと思います。

フィルタ

「天気(日中)」のフィールドに「曇」または「雨」が含まれている日数を表示します。
MetricsをCountにし、以下のようにOptionを設定します。
f:id:acro-engineer:20180930101428p:plain

データをちゃんと加工していないので、「晴時々薄曇」みたいな天気までヒットしてしまうのが微妙です。
ただ、確かにこの月の北海道は三都市で一番天気が悪いようです。
f:id:acro-engineer:20180930101447p:plain

まとめ

Visual Builder Tableのスクリプトで「割合」を計算したり、計算結果に対して条件書式を付ける事で異常値を強調表示できました。

一見シンプルながら色々な可能性を感じるVisualizeになっています。
Experimental機能のため公式ドキュメントが整備されておらず、触りながら慣れる形になりますが、ぜひ一度試してみてください。

それでは。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

雑誌「Interface」2018年12月号に「AI猫カメラ」の特集記事を寄稿しました

hayakawaです。
10月25日発売の雑誌「Interface」2018年12月号に、
後輩の@tereka114さんと共同で執筆した「AIひょっこり猫カメラ」という特集記事を寄稿しました。

f:id:acro-engineer:20181011161140j:plain:h300
Interface 2018年12月号

2018年12月号 | Interface – CQ出版

カメラ付きのRaspberry Piに猫を判定できるAIを入れ、猫を見つけてはTwitterに投稿するBotを作成する、という内容です。

実際に動いているところ

こちらのTwitterアカウントにてBotが動いています。

twitter.com

5分おきに動き、撮影したカメラ画像に猫が写っているときに投稿します。
このBot入りのRaspberry Piは、NPO法人「東京キャットガーディアン」様の設備である、保護猫カフェ「大塚スカイシェルター」に設置させていただいております。

tokyocatguardian.org

行政などから保護された猫と、猫カフェの形式で触れ合える人気施設です。

f:id:acro-engineer:20180901131518j:plain:h300

よって、ツイートされた画像に、お気に入りの、猫ちゃんが写っていれば、
(先客がいなければ)引き取りを希望することができるのです!!

※ただしきちんと責任をもって猫を飼える状態かの面談があります。

詳しくは上記の東京キャットガーディアン様のサイトにてご確認ください。

技術的な内容

f:id:acro-engineer:20180830110554j:plain:h300

構成としては、

  • Raspberry Pi 3に小型カメラを接続
  • Keras上で、学習済みの画像判定モデル(MobileNet)動かし、画像判定
  • 猫が写っていたらTwitter APIで画像を投稿

というシンプルな内容です。

コンセプトとしては、世にある学習済みモデルをそのまま使って、時間のかかるディープラーニングの学習処理をせずに、カンタンに動くものを作る、というものでした。

猫を題材にしたのは、猫を写せば一定数のファンがつくだろうという浅はかな考えによるものです。
ごめんなさい。

しかも最初は、オッサン(私)の構えた猫写真ボードで動作確認をするという絵面とアタマの悪い内容でしたが、CQ出版様の交渉により、実物の猫ちゃんが満杯の猫カフェに実機を入れるというシチュエーションにしていただけました。
ありがとうございます。

雑誌の内容

以下のようなことを書きました。

  • Kerasで学習済みモデルをロードして動かす方法
  • 初心者向け、Raspberry Piのセットアップ方法
  • Raspberry PiにTensorFlowとKerasをインストールする方法
  • 実際に画像判定を動かしたうえでの問題と対策
  • Twitter APIの使い方
  • ファインチューニングのやり方

特にRaspberry PiにTensorFlowなどのAIを入れる構成は、色々と使い道があって、やってみたい方もそこそこいらっしゃると思いますが、ハマりどころもそこそこあるので、雑誌の内容を参考にしていただけると幸いです。

なお原稿を書いてる間に、

  • TensorFlowが正式にRaspberry Piに対応
  • Twitter API用の開発者アカウントの取得が難しくなる

など、色々ありましたがなんとか形になりました。

設置

CQ出版の編集様と一緒に大塚スカイシェルターにお邪魔し、設置してきました。

f:id:acro-engineer:20180901131500j:plain:h300

職員の方から

  • ケーブルを表に出すのはオススメしない。必ず引っかかれる。
  • 固定しないのはオススメしない。必ず叩き落される。
  • とにかく猫は新しいモノをすぐに嗅ぎつける。気を付けろ。

と親身にアドバイスをいただきまして、ケーブルをカバーで覆ったうえでケースは本棚に厳重にねじ止めされています。

f:id:acro-engineer:20180901131444j:plain:h300

予期せず猫に関する知見を得られました。
良い仕事でした。

ということで雑誌は発売中ですが、
そんな難しいことはどうでもいいという方は猫の画像をご覧になっていってください!
f:id:acro-engineer:20181025190613j:plain:h300

f:id:acro-engineer:20181025190632j:plain:h300

f:id:acro-engineer:20181025190641j:plain:h300

f:id:acro-engineer:20181025190619j:plain:h300

よければ雑誌の方もよろしくお願いします!

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
最先端の機械学習を活用して表情認識に挑戦! - Acroquest Technology株式会社のエンジニアインターンシップの求人 - Wantedlywww.wantedly.com