かまたま日記3

プログラミングメイン、たまに日常

Datadog LogsをCLIでtailするツールを作った

github.com

モチベーションとしては、Datadog LogsのWebコンソールはメッセージの全文が長いと全部表示されなかったり普通のtailと違って時間の降順に並んだりで微妙に見づらかったりするので、CLItail -fコマンド感覚で見れて雑にgrepとかしたいと思って作りました。

インストール

Releases からバイナリをダウンロードしてパスを通してください。
あと多分 go get -u github.com/kamatama41/taildog でもインストールできると思います。

使い方

まず、DD_API_KEYDD_APP_KEY (application key) の2つの環境変数を設定する必要があります。DatadogのWebコンソールから取得してきてください。

全ログを追跡する

$ taildog

クエリで絞り込む

$ taildog -q "service:my-app"

一定期間のログを表示する (追跡はしない、 max 1000行)

$ taildog -q "service:my-app" --from 2019-07-10T11:00:00Z --to 2019-07-10T11:00:05Z

出力のフォーマットを変える

Goのtemplateのスタイルで記述します。使用できる項目はDatadogのLog Query APIのレスポンスのcontentの内容に準拠します。 デフォルトは "{{.Timestamp}} {{.Host}} {{.Service}} {{.Message}}" です。

$ taildog -q "service:my-app" -f "{{.Timestamp}} {{.Message}}"

注意

  • 実際にログがインジェストされてからAPIで見れるようになるまで、微妙にタイムラグ (5~30秒くらい) があります。
  • Log Query APIは300回/時間/組織のレートリミットがあるので*1、複数人で長時間使うとエラーになる可能性があります。
  • 上記の理由からデフォルトで15秒おきにポーリングするようにしていて、そこまでリアルタイム性は高くないです。

よかったら使ってみてください〜!

*1:必要に応じで拡張はできるそうです

Mercari meetup for SRE Vol. 2 に参加してきた

mercari.connpass.com

データセンタープロジェクトの進捗って言うのが面白そうで抽選通ったので参加してきました。基本的には今自分が所属している小さいスタートアップでは直接的に参考になることはあまり無かったですが、こういうスケールの大きな話を聞くのは刺激になりました。その後の懇親会では負荷試験をどうやってするかと言うのをメインで話して、みんな「やりたいけど環境作るのが難しいよね」という感じで意見が一致しました。

Percona XtraDB Clusterに寄り添う @ichirin2501

Percona XtraDB Cluster を使ってMySQLクラスタリングを一つのサービスに適用してみた話。

  • ロードバランシングにProxySQLを使おうと思ったけどはまりポイントが多くてHAProxyに落ち着いた
  • PXC5.7.16から5.7.17で10倍ぐらいの性能の差がある
  • 移行後, DBのCPU使用率は2倍になったが、もともとのデッドロックを解消したら半分になった
  • 将来的には社内RDSとして提供していく予定

Progress of Data Center Project @kazeburo

去年発表した自社DC (TC) のその後のお話

  • Google <-> TC はグローバルで繋がっていて さくら石狩 <-> TC はプライベートで繋がっている
  • Google -> TC -> さくら の場合、TCでSSL終端しそこからhttpでさくらに渡す
  • さくら -> TC -> Googleの場合 chocon をさくらとTCの2段置いて使っている
  • 16kvaを使って(?) ラックの凝縮度を上げる・それに合わせた空調も整備
  • DB as a serviceを提供するためにDB-Gatewayを作った
    • Gatewayはwebsocketをしゃべって裏のDBのプロキシをする
      • Go言語のRegisterDialを使うイメージ
    • 認証は deteco を使って行う
  • 将来的にはマルチクラウドのハブだったり金融機関との連携などでもTCを活用していく予定

DockerのUbuntuコンテナでsystemdを動かす

TL; DR

  • とりあえず --privileged をつける。つけないでいい感じで動かすのは大変そう。
  • CentOSは公式でsystemd用のベースイメージを用意してくれているので、Ubuntuを使いたい人以外はそちらを使うのが良さそう
  • STOPSIGNAL SIGRTMIN+3 をつける

FROM ubuntu:18.04

RUN apt-get update \
 && apt-get install -y \
    openssh-server \
 && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /var/run/sshd && chmod 755 /var/run/sshd

ARG GITHUB_USER
# ADD ubuntu user, and set password and public key
ADD https://github.com/${GITHUB_USER}.keys /home/ubuntu/.ssh/authorized_keys
RUN useradd -u 1000 ubuntu \
 && usermod -s /bin/bash -G adm,sudo ubuntu \
 && echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
 && mkdir -p /home/ubuntu && chown -R ubuntu.ubuntu /home/ubuntu

STOPSIGNAL SIGRTMIN+3
CMD [ "/sbin/init" ]

例えばこんな感じのDockerfileでSSHサーバをsystemd経由で起動しようとすると、想定どおりに動作していません。 (ubuntuユーザでコンテナにSSH出来ない)

$ docker build --build-arg GITHUB_USER=${GITHUB_USER} -t kamatama41-ubuntu-systemd-test .

$ docker run -p 2222:22 -d --rm kamatama41-ubuntu-systemd-test
1faf7f57aabba3ccb935cbc3de84224f304021c87a31a7487164a2ac157e33b1

$ ssh ubuntu@localhost -p 2222
ssh_exchange_identification: Connection closed by remote host 

docker runのときに --privileged オプションを付けると想定通りの動きになります。

$ docker run -p 2222:22 -d --privileged --rm kamatama41-ubuntu-systemd-test
f4adaea692edd55bdc059536cebe3b5aac03d842af33c0b902bb79ccb1251e3a

$ ssh ubuntu@localhost -p 2222                                             
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.9.125-linuxkit x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ubuntu@f4adaea692ed:~$ 

とりあえず、テスト用途で動かす場合はこれで大丈夫そうですが、本番では使わない方が良いでしょう。ググった感じsystemdをnon-privilegedなUbuntuのコンテナで動かすのは結構大変そうです。

CentOSは公式でsystemd用のベースイメージを提供してくれているので、本番で使いたい場合はこちらを使うのが良いでしょう。

あと1点注意点として、systemdのコンテナを止めるときは SIGRTMIN+3 を使わないといけないようなので、 STOPSIGNAL を変えてあげておきましょう。

GolangでForループの中でdeferしない

defer はそれが定義された関数が終わったタイミングで実行されるので、forループでdeferを定義してしまうと、forループが終わって所属する関数が終わったタイミングで一斉に実行される。

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        println(fmt.Sprintf("Main %d", i))
        defer closeResource(i)
    }
}

func closeResource(i int) {
    println(fmt.Sprintf("Close %d", i))
}

例えばこれを実行すると

Main 1
Main 2
Main 3
Main 4
Main 5
Close 5
Close 4
Close 3
Close 2
Close 1

こういう出力になる。これはDBコネクションなどの場合、リソースリークにつながるのであまりよろしくない。こういう場合はforのブロックを別関数に移すか、無名関数でラップするのが好ましい。

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        func() {
            println(fmt.Sprintf("Main %d", i))
            defer closeResource(i)
        }()
    }
}

func closeResource(i int) {
    println(fmt.Sprintf("Close %d", i))
}

こうすれば、期待通りの結果になる

Main 1
Close 1
Main 2
Close 2
Main 3
Close 3
Main 4
Close 4
Main 5
Close 5

参考 go - `defer` in the loop - what will be better? - Stack Overflow

退職しました4

TwitterFacebookでフォローされてる方は知っているかと思いますが、3月末で前職を退職していました。短い間ですがお世話になった皆さんありがとうございました。1年弱という社会人生活で一番短い在職期間になりました。

これまで

Hosted Embulk for TDである、DataConnector/ResultOutputという2つのサービスをメンテナンスするチームに所属していました。そこで新規/既存のEmbulkプラグインの開発、Embulk本体のメンテナンス、サービスを提供するためのアプリケーション開発、実行環境や開発環境の改善など主にバックエンド周りのことをやっていました。また、夏ごろにアメリカ出張に行ったことは人生初のアメリカということもあって、とても良い経験になりました。

現在

SEQSENSEという警備ロボットを開発しているベンチャー企業に4月から所属しています。コアとなる強みは自律移動ロボットの開発能力でロボット界隈では結構有名な会社のようです。自分が担当しているのはバックエンド周り全般で、具体的には以下のようなものがあります。メインとなる言語はGoなので勉強中です。

  • ロボットをWebから管理するためのアプリケーション開発
  • ロボットとのコネクティビティ周り
    • AWS IoTを使ったMQTTでのやりとり
    • ロボットと動画、音声をやり取りする*1ためのサーバ開発
  • 外部システム *2 との連携
  • 全体のインフラ*3、開発環境構築、改善

恥ずかしながらインタビューもしてもらったので、会社についてや転職の理由など詳しいところはこちらを見て頂ければと思います。

興味を持たれた方はぜひDMなりでご連絡いただくか、Wantedlyで応募してください、お待ちしております m(_ _)m

*1:via WebRTC

*2:ビル内の設備

*3:AWS

Goで複数バージョンを管理する

まあここに書いてることそのままなのですが、日本語のメモとして。

go get でダウンロード用のバイナリを取ってきて、downloadコマンドを打つ

$ go get golang.org/dl/go1.12.5
$ go1.12.5 download
Downloaded   0.0% (    15175 / 127612395 bytes) ...
Downloaded   5.0% (  6438912 / 127612395 bytes) ...
Downloaded  14.0% ( 17874944 / 127612395 bytes) ...
Downloaded  23.0% ( 29310976 / 127612395 bytes) ...
Downloaded  32.0% ( 40812544 / 127612395 bytes) ...
Downloaded  41.0% ( 52281344 / 127612395 bytes) ...
Downloaded  49.6% ( 63262720 / 127612395 bytes) ...
Downloaded  56.7% ( 72312832 / 127612395 bytes) ...
Downloaded  65.7% ( 83846144 / 127612395 bytes) ...
Downloaded  74.8% ( 95437556 / 127612395 bytes) ...
Downloaded  81.9% (104570610 / 127612395 bytes) ...
Downloaded  90.8% (115831263 / 127612395 bytes) ...
Downloaded  97.1% (123951181 / 127612395 bytes) ...
Downloaded 100.0% (127612395 / 127612395 bytes)
Unpacking /Users/kamatama41/sdk/go1.12.5/go1.12.5.darwin-amd64.tar.gz ...
Success. You may now run 'go1.12.5'

GOROOTgo env GOROOTで分かるので、GoLandとかIntelliJとかで使いたい場合はそこをSDKとして指定する。アンインストールする場合はGOROOTディレクトリを消す。

$ go1.12.5 env GOROOT
/Users/kamatama41/sdk/go1.12.5

embulk-executor-remoteserver 0.4.0 リリース

github.com

このバージョンより、Embulk clientとserver間でTLSでの接続ができるようになりました。

設定方法 (クライアント)

まず、use_tls オプションをtrueに設定してください。サーバ側が(クライアントにとって)既知のCA証明書でサインされた証明書を使っていれば、これだけでOKです*1

exec:
  type: remoteserver
  hosts: ...
  use_tls: true

そうでない場合は、CA証明書をca_cert_pathに追加してください

exec:
  type: remoteserver
  hosts: ...
  use_tls: true
  ca_cert_path: path/to/ca.cert.pem

クライアント認証が必要な場合、クライアント証明書と秘密鍵がセットになったPKCS12ファイルのパスとパスワードをcert_p12_fileで指定してください。

exec:
  type: remoteserver
  hosts: ...
  use_tls: true
  cert_p12_file:
    path: path/to/cert/client.p12
    password: xxxxx

設定方法 (サーバ)

EmbulkサーバをTLSの終端にする場合*2、以下の環境変数を設定してサーバを起動してください

  • USE_TLS=true: TLS接続を有効にする
  • REQUIRE_TLS_CLIENT_AUTH=true: クライアント認証を有効にする
  • CERT_P12_PATH, CERT_P12_PASSWORD: サーバ証明書秘密鍵のペアのPKCS12ファイルパスとパスワード
  • CA_CERT_PATH: CA証明書のパス。クライアント証明書が(サーバにとって)未知のCA証明書でサインされてる場合に必要

例えばdocker-composeで設定する場合以下のようになるかと思います

version: '3'
services:
  server:
    image: kamatama41/embulk-executor-remoteserver
    ports:
      - "30001:30001"
    volumes:
      - ./certs:/root/certs
    environment:
      USE_TLS: "true"
      REQUIRE_TLS_CLIENT_AUTH: "true"
      CERT_P12_PATH: /root/certs/embulk-server.local.p12
      CERT_P12_PASSWORD: xxxxx
      CA_CERT_PATH: /root/certs/ca.cert.pem

*1:たぶん、未確認

*2:前段にAWS NLBやNGINXを置いてそこを終端にするなども多分できると思います