LoginSignup
1
0

More than 5 years have passed since last update.

CloudWatchLogsの通知をLambdaで受け取る

Last updated at Posted at 2017-02-03

概要

CloudWatchLogsのログイベントをAWS LambdaでClojure使って取得したらけっこう面倒だった

CloudWatchLogsの仕様

サブスクリプションフィルタの使用 - AWS Lambda

Lambda の配列を含むレスポンスが表示されます。Lambda レコードの [Data] 属性は、Base64 でエンコードされており、gzip 形式で圧縮されています。Lambda が受け取る実際のペイロードは、{ "awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"} } の形式になります。raw データは、コマンドラインから次の UNIX コマンドを使用して調べることができます。

結構面倒だぞ、最初Base64だけかと思ってたけどGZIP圧縮もされてる。

Java8あるしClojure使おう

設定は Writing AWS Lambda Functions in Clojure を参考にした

ソースサンプル

  • テストデータがJSON型だとイベントハンドラの関数もそれに対応した型を宣言しないとだめっぽい
    • (defn -handleEvent [^java.util.HashMap m] ← これ
    • それをClojureのMapに変換 (def am (into {} m))
    • get-inで取り出し (def data (get-in am ["awslogs" "data"])) Rubyのdig関数っぽい
core.clj
(ns core
  (:import org.apache.solr.common.util.Base64)
  (:import java.io.ByteArrayInputStream)
  (:import java.util.zip.GZIPInputStream)
  (:import org.apache.commons.io.IOUtils)
  (:gen-class
   :methods [^:static [handleEvent [java.util.HashMap] String]]))

(defn -handleEvent [^java.util.HashMap m]
  (def am (into {} m))
  ;; CloudWatchLogsはBase64形式で来る => {awslogs={data=XXX}}
  (def data (get-in am ["awslogs" "data"]))
  (println (str "aws cloud logs with Base64 => " data))

  ;; デコードしてGZIP解凍するべし
  (let [bytes (Base64/base64ToByteArray data)
        bi (new ByteArrayInputStream bytes)
        zi (new GZIPInputStream bi)
        json (IOUtils/toString zi)]
    ;; やっと表示
    (println (str "aws cloud logs => " json)
    json)))

ライブラリは以下を使用した

project.clj
[org.apache.solr/solr-solrj "6.0.0"]
[commons-io/commons-io "2.5"]
[com.amazonaws/aws-lambda-java-core "1.1.0"]

Clojureをもっと使っていきたい

1
0
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
1
0