カテゴリー: redash

  • FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed – JavaScript heap out of memory

    FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed – JavaScript heap out of memory

    はじめに

    redash v8 のリポジトリを clone して コンテナを build しようとすると、

    ` FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed – JavaScript heap out of memory `

    というエラーになった。

    FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
    
    Writing Node.js report to file: report.20200305.111353.33.0.001.json
    Node.js report completed
     1: 0x9dab70 node::Abort() [node]
     2: 0x9dbd26 node::OnFatalError(char const*, char const*) [node]
     3: 0xb3b18e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
     4: 0xb3b509 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
     5: 0xce68a5  [node]
     6: 0xce6f36 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node]
     7: 0xcf2dca v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
     8: 0xcf3cd5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
     9: 0xcf66e8 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [node]
    10: 0xcbd017 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType) [node]
    11: 0xff307b v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
    12: 0x1376259  [node]
    Aborted (core dumped)
    npm ERR! code ELIFECYCLE
    npm ERR! errno 134
    npm ERR! redash-client@9.0.0-alpha build: `npm run clean && NODE_ENV=production webpack`
    npm ERR! Exit status 134
    npm ERR! 
    npm ERR! Failed at the redash-client@9.0.0-alpha build script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    ERROR: Service 'server' failed to build: The command '/bin/sh -c npm run build' returned a non-zero code: 134

    原因

    マシンのメモリーが足りない。

    https://redash.io/help/open-source/dev-guide/docker

    v8 のイメージをbuild するには最低限 4G のメモリーが必須となるようだ。

    ビルドするマシンのメモリーを増やすことによって解決できた。

     

     

     

  • redash API で パラメータを動的に変えてクエリを受け付ける

    redash API で パラメータを動的に変えてクエリを受け付ける

    tl;dr;

    redash API で パラメータを動的に変えてクエリを受け付ける方法を紹介します。

    サードパーティを使わず行います。今回の version は redash v6ですがおそらくそれ以降でも可能かと思います。

    手順をご紹介する前の前提条件

    私の環境では検証環境としてすぐ起動できる redash の環境を利用します。

    # git clone
    git clone https://github.com/GitSumito/redash-blue.git
    cd redash-blue
    
    # DB 初期化
    docker-compose run --rm server create_db docker-compose up
    
    # 起動
    docker-compose up -d  

    http://127.0.0.1/ へ接続し、データソースの設定などを適宜行います。

    DBのcredential 情報などは下記をご覧ください。

    https://github.com/GitSumito/redash-blue/blob/master/README.md

     

    動的クエリを作成する

    その後、 Create -> Query に移動し、変数を受け付けるカラムを書きます。

    この場合はクエリを code という引数で受け取ります。

     code に JPN といれると、redash が where ContryCode = "JPN"と組み立ててくれる仕組みです。

    これをブラウザからではなく、RestFull API で行うようにするというのが今回の趣旨です。

    作成した Query は publish してください、

    事前準備

    ユーザーのAPI keyを確認します。

    http://127.0.0.1/users/1

    を開けばAPI keyを確認することができます。

    このAPI keyを確認します。

    ジョブを登録する

    引数は p_xxxx というパラメータ名で受け付けるようです。
    code という引数を設定したので、今回は p_code というパラメータ名になりました。

    これを POST で送ります。curl コマンドで行うとやりやすいかと思います。

    curl --request POST \
    --url 'http://127.0.0.1/api/queries/1/refresh?p_code=IND' \
    --header 'Authorization: Key ajxxxxxxxxxxxxxxx'

    受け付けられると、 以下のようなレスポンスが返ってきます。

    ID を控えてください。今回登録したジョブを、以下のIDを用いて確認することができます。

    query_result_id を確認する

    ジョブのIDをパスパラメータとして渡します。

    また、api_keyを後ろにつけてください。

    curl "http://127.0.0.1/api/jobs/93452aa6-8569-43fc-b816-cb441ce80e03?api_key=ajxxxxxxxxxxxxxxx"

    query_result_id が返ってきます。こちらを用いて結果を確認します。

    query_result_id を用いて結果を確認する

     

    curl -s -H 'Authorization:Key ajxxxxxxxxxxxxxxx' -H 'Accept:application/json' -H 'Content-Type:application/json' http://127.0.0.1/api/query_results/8
    

    以下の通り、ContryCode `IND`の情報を取得することができました。

    今回の version は redash v6ですがおそらくそれ以降でも可能かと思います。

  • docker v7 install

    docker v7 install

    はじめに

    公式リポジトリをclonesに、従来のコマンドでredash v7をインストール

    $ docker-compose run --rm server create_db
    
    $ docker-compose up -d

    を試みたところ以下のようなエラーが発生した。

    Browserslist: caniuse-lite is outdated. Please run next command `npm update caniuse-lite browserslist`
    Killed
    npm ERR! code ELIFECYCLE
    npm ERR! errno 137
    npm ERR! redash-client@8.0.0-beta build: `npm run clean && NODE_ENV=production node --max-old-space-size=4096 node_modules/.bin/webpack`
    npm ERR! Exit status 137
    npm ERR! 
    npm ERR! Failed at the redash-client@8.0.0-beta build script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /root/.npm/_logs/2019-09-03T05_01_25_105Z-debug.log
    ERROR: Service 'server' failed to build: The command '/bin/sh -c npm run build' returned a non-zero code: 137

    node.js系のエラー?

    docker-compose.ymlを覗いてみると、Dockerfileからビルドする作りになっている。
    コンテナ内部でうまくインストールできなかったのだろうか。

    対処

    インストールで時間を使いたくないのでDocker hubから出来合いのDocker imageをpullして動かすことにした。

    作成したdocker-compose.ymlはこちら。

    https://github.com/GitSumito/redash-v7

    使い方は簡単。

    git clone https://github.com/GitSumito/redash-v7.git
    cd redash-v7
    docker-compose run --rm server create_db
    docker-compose up -d

    これでとりあえず起動することができる。

    http://localhost/setup

    参考情報

    docker-compose.yml を作成する際、非常にお世話になった。カックさんのhandson資料。

    https://github.com/kakakakakku/redash-hands-on

     

     

  • SQLiteで小数点が入る割り算を行う

    SQLiteで小数点が入る割り算を行う

    はじめに

    redashでQuery Resultを利用するとSQLiteを利用することができる。

    ただし、SQLite内で割合を計算をするような処理をすると、0になってしまうので、一工夫必要になる

    SELECT success  / try  * 100 AS ratio,
           success ,
           try

    解決策

    castと、roundを利用し、小数点以下の計算に対応させる。

    SELECT round(cast(success as REAL) / cast(try as REAL),5) * 100 AS ratio,
           success as success ,
           try as try

     

     

     

  • postgresのシーケンス一覧を取得ならびに変更する

    postgresのシーケンス一覧を取得ならびに変更する

    はじめに

    redashの内部のDBはpostgresだが、version upを繰り返すうちにDB構成がバグってしまった。具体的には外部キーや、Indexなのが外れてしまった。

    根本対応としては再度イチからredashを作り、そこにデータを一個一個転送することになるとおもうが、なかなかその対応にたどり着けず、一時対応でとりあえず問題を先送りしている。

    ちなみにusersテーブルの場合、以下の部分がごっそり無くなっていた

    Indexes:
        "users_pkey" PRIMARY KEY, btree (id)
        "users_api_key_key" UNIQUE CONSTRAINT, btree (api_key)
        "users_org_id_email" UNIQUE, btree (org_id, email)
    Foreign-key constraints:
        "users_org_id_fkey" FOREIGN KEY (org_id) REFERENCES organizations(id)
    Referenced by:
        TABLE "access_permissions" CONSTRAINT "access_permissions_grantee_id_fkey" FOREIGN KEY (grantee_id) REFERENCES users(id)
        TABLE "access_permissions" CONSTRAINT "access_permissions_grantor_id_fkey" FOREIGN KEY (grantor_id) REFERENCES users(id)
        TABLE "alert_subscriptions" CONSTRAINT "alert_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "alerts" CONSTRAINT "alerts_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "api_keys" CONSTRAINT "api_keys_created_by_id_fkey" FOREIGN KEY (created_by_id) REFERENCES users(id)
        TABLE "changes" CONSTRAINT "changes_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "dashboards" CONSTRAINT "dashboards_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "events" CONSTRAINT "events_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "favorites" CONSTRAINT "favorites_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "notification_destinations" CONSTRAINT "notification_destinations_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "queries" CONSTRAINT "queries_last_modified_by_id_fkey" FOREIGN KEY (last_modified_by_id) REFERENCES users(id)
        TABLE "queries" CONSTRAINT "queries_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
        TABLE "query_snippets" CONSTRAINT "query_snippets_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    

    その結果、Edit Visualizationで保存ができなくなった。

    コンテナのログを見たら、本来1つしかないはずが2つ以上ヒットするよ。とエラーになっているのが原因だとわかった。

    シーケンスで指している数字が、すでにレコードとして存在していたのが問題だ。

    今回はシーケンスを変更することで対処した。

    Postgresのシーケンス一覧を表示する

    “` SELECT c.relname FROM pg_class c LEFT join pg_user u ON c.relowner = u.usesysid WHERE c.relkind = ‘S’; relname  “` で表示できる。

    redashに限らず、どのPostgresでも対応可能。

    postgres=# SELECT c.relname FROM pg_class c LEFT join pg_user u ON c.relowner = u.usesysid WHERE c.relkind = 'S';
                 relname              
    ----------------------------------
     access_permissions_id_seq
     alert_subscriptions_id_seq
     alerts_id_seq
     api_keys_id_seq
     changes_id_seq
     dashboards_id_seq
     data_source_groups_id_seq
     data_sources_id_seq
     events_id_seq
     favorites_id_seq
     groups_id_seq
     notification_destinations_id_seq
     organizations_id_seq
     queries_id_seq
     query_results_id_seq
     query_snippets_id_seq
     users_id_seq
     visualizations_id_seq
     widgets_id_seq
    (19 rows)
    
    postgres=#

    シーケンスの値を確認する

    postgres=# select nextval('visualizations_id_seq');                                                                                                                                                                  nextval 
    ---------
          56
    (1 row)

    56ということがわかる

    シーケンスの値を変更する

    ALTER SEQUENCEコマンドで変更が可能

    postgres=# ALTER SEQUENCE visualizations_id_seq RESTART WITH 251;
    ALTER SEQUENCE

     

    結果、redashが正常に動くようになった。

    おそらくversion upを繰り返しているうちに、どこかでDBスキーマが壊れてしまった可能性がある。

     

    関連記事

    https://tsukada.sumito.jp/2018/10/11/redash_all-queries_loading/

    redash を専門に扱っている唯一の本

  • redashが正常に動いているか、どう監視するか。

    redashが正常に動いているか、どう監視するか。

    メリークリスマス⛄️
    本記事はredash advent calendarの12/24の記事です。

    はじめに

    redashはさまざまな人が使うツールへと発展してきました。

    それに応じてredashは常に安定稼働していなければならない必要性も高まってきています。

    redashの状態監視がますます必要な状態になりました。

    redashの監視といえば、status.jsonというものがあります。
    https://kakakakakku.hatenablog.com/entry/2017/12/21/025718

    これを使えば、いまredashがどれだけのクエリが保存されていて、memoryを使っていて。。。ということがわかるのですが。。

    しかしある時、API経由で使っている人が「redashの返すクエリの結果が変わらないんだけど。。。」という問い合わせを受けました。

    redash自体ハングしていたら、この状態はstatus.jsonではわからないのです。

    redashが”機能的に正常に動いているのか、監視する必要がでてきました。

    どうやるか

    “機能的に”動いているかを確認したいのであれば、”機能的に”監視するのが一番。

    redashでは単純に現在時間を返すクエリを登録します

    SELECT to_char(now() + interval '9hour'  , 'YYYY/MM/DD HH24:MI:SS');

    データソースはredashの持つpostgresにしました。

     

    redashを監視サーバからAPIで叩きに行き、

    前回実行した時間を差分を取るという仕組みです。

    前回と違う結果だったら問題なし。同じ結果だったら”異常”とみなす。

     

    監視サーバには以下のシェルを置きました。

    # cat  ./redash_monitor.sh 
    #!/bin/bash
    
    # redashに問い合わせ(cache clear)
    $(curl -s https://redash-url.jp/api/queries/309/refresh?api_key=HoZrcikN0uhqNnaAPUtHKhogehogehogehoge -X POST > /dev/null )
    
    sleep 30;
    # 現在の値を取得
    curl -s https://redash-url.jp/api/queries/309/results.json?api_key=HoZrcikN0uhqNnaAPUtHKhogehogehogehoge  | jq -r '.query_result.data.rows[].to_char ' > /tmp/monitor.txt.tmp
    
    # 差分を比較する。差分があれば通知。
    diff /tmp/monitor.txt.tmp.previous /tmp/monitor.txt.tmp
    
    if [ $? -eq 0 ]; then
      # 文字を整形する
      # headder
      cat << _EOT_ > /tmp/msg.txt
      [info]
      [title] Redash might not work well
      [/title]
      Oh my Gush!! Your redash might not work well
      [/info]
      _EOT_
    
      _roomid=1234567890
      _body=`cat /tmp/msg.txt`
      curl -X POST -H "X-ChatWorkToken: 9aaefddccc40hogehogehogehoge" -d "body=${_body}" "https://api.chatwork.com/v2/rooms/${_roomid}/messages"
    fi
    
    mv /tmp/monitor.txt.tmp /tmp/monitor.txt.tmp.previous

     

    我々の環境はchatworkを使っているので、宛先はchatworkになっています

    これをcronに登録し定期的に実行するようにしています。

    最後に

    大活躍する機能。と思いたいけど実はredash自体が優秀なためそれほど日の目を見る事はないのです。。
    だけどこの監視を設定していると、いち早くredashの不具合に検知することができます。

    ちなみにredashがおかしくなったら、serverやworkerコンテナを消してもう一度作り直すのが多いです。

    明日は @ariarijp さんによる記事です!
    https://adventar.org/calendars/3299#list-2018-12-25

  • redashで誰が何のクエリを投げたのかMySQL側で確認する

    redashで誰が何のクエリを投げたのかMySQL側で確認する

    はじめに

    MySQLはredashで最も多く使われるデータソースの一つです。

    MySQLにつなぐ際、用途ごとにユーザーを作成するのが一般的な運用だと思います。

    我々はredashも例外ではなく、redash用に”redash”というアカウントをDBに登録しています。つまり、redashからMySQLに接続する際”redash”というユーザーが繋ぎに行くことになります。

    そのため、DB側でみると、すべてが”redash”ユーザーになってしまうと思い込んでいたので、MySQL側から「誰が何をやったのか」はわからないはず。と思ってました。

    ※ redashは version 6 bata版を使っています。

    実際はどうなのか

    実はredashからMySQLに送られるデータはコメント欄にredashのアカウントが記載されています。

    +-------+-------------+---------------------+-----------+-------------+---------+-----------------------------------------------------------------------------+------------------+|
    | Id | User | Host | db | Command | Time | State | Info |
    |+-------+-------------+---------------------+-----------+-------------+---------+-----------------------------------------------------------------------------+------------------+| 
    | 23745 | redash | 172.1.2.25:58582 | mysqldb | Query | 123 | preparing | /* Username: tsukada@sumito.jp, Task ID: 86611845-6b88-4b82-b1e3-6951236f8ad6, Query ID: adhoc, Queue: queries, Query Hash: f175924439bfb73a2df8c81234567890 */ SELECT s.id, s.date FROM sample s |https://tsukada.sumito.jp/wp-admin/post.php?post=691&action=edit# | 

    上記からわかる通り、実施するクエリの前に以下の部分がコメントとして追加されてます。

    /* Username: tsukada@sumito.jp, Task ID: 86611845-6b88-4b82-b1e3-6951236f8ad6, Query ID: adhoc, Queue: queries, Query Hash: f175924439bfb73a2df8c81234567890 */

    このUsernameはredashに登録されているユーザのメールアドレスになるのが注意です。

    show processlist;

    と組み合わせて、誰が重いクエリを投げているのか、DB側からも誰が何を実施したのかトレースが可能です。

    さいごに

    他のデータソースは試してないので、
    もしご存知の方いらっしゃったら

    Redash Advent Calendar ( https://adventar.org/calendars/3299 )

    に記載してぜひ教えてください。

  • redashの導入、運用で得た知見、改善まとめ

    redashの導入、運用で得た知見、改善まとめ

    はじめに

    redashは去年の年末頃Version 4が出て、夏にVersion 5、そしてVersion 6が近日リリースというスピードで、どんどんメジャーバージョンアップを繰り返し、機能が拡充されています。

    レアジョブではDocker版 redash Version 1.03で初めてredashを導入し、何度もVersion UPを繰り返し現在は最新版(5.02)を使っています。

    そこで得た知見についてはメモを書いていましたが、( https://tsukada.sumito.jp/category/tech/redash/ ) あくまでもメモベースなので、これを機にちゃんとブログとしてまとめたいとおもいます。

    弊社での利用者

    アルバイトから役員まで、様々なロールを持ってる人が使ってます。

    Botも動いており、一部APIを使い、Chatに通知する仕組みも取り入れています。

    SQLを書ける人を増やしたい

    最初は非エンジニアの方は書けない人が大半でした。

    社内勉強会を定期的に開き、誰でもSQLを書ける土台を作りました。

     

    社内勉強会の成功は「自分ゴト化」がキモ。非エンジニアにSQLを教えた話

    https://appeal.rarejob.co.jp/2016/11/11/2174/

    それでもすぐにSQLが書けるようにはならないので、足りない部分はchatで専用の窓口を開き、SQLやredashについて気軽に質問できる土台を作りました。

     

    redashの使い方についてはkakakakakkuさんのhandson資料を使わせてもらい、社内でredash使える人を増やしました。

    https://github.com/kakakakakku/redash-hands-on

    APIを使いたい

    残念ながらAPIについてのドキュメントはあまりありません。

    ソースを見るのが一番早かったりします。

    https://github.com/getredash/redash/blob/master/redash/handlers/api.py

    運用編

    redashのコンテナの役割を知りたい

    以前Qiitaにまとめた記事にredash_serverコンテナがどのような振る舞いをしているのかまとめた。

    https://qiita.com/S-T/items/bee0ae9c8c0acbd940cc

     

    redashのバックアップを取りたい

    基本的にredashのデータはredashのPostgresに入ります。redisはキャッシュ情報が入るのでこちらはバックアップの対象外で問題ありません。(自分はクエリが詰まったらredisの中身を全部空にしたりします)

    我々はDockerで動かしているので、host側から以下のcronを仕込んでます。

    0 6 * * * /bin/docker exec redash_postgres_1 pg_dump -U postgres postgres | /bin/gzip > /tmp/redash_backup.gz

    このバックアップで取得できたファイルを、定期的に別サーバやS3に格納しています。

    redashのクエリのバックアップを取りたい

    redashに登録したクエリをバックアップし、世代管理したい事が多々あります。

    @ariarijp さんが作成した redashman (https://github.com/ariarijp/redashman) というツールが非常に便利です。

    どこでも動くように、という事を念頭に開発されたようでgo言語で作られています。

    定期的に実行し、gitで保存するようにしています。

    redashのメジャーVersion UPをしたい

    オフィシャルの手順はこちらです。

    https://redash.io/help/open-source/admin-guide/how-to-upgrade

    作業前にPostgresのバックアップを取得することを強くお勧めします。

     

    私がVersion UPした際の手順は以下の通りです。

    メジャーバージョンアップを行う場合、DBのスキーマ変更を伴う場合が多いです。

    https://tsukada.sumito.jp/2018/08/08/docker-redash-v5-update/

    redashのマイナーバージョンアップをしたい

    docker-composeでdockerのイメージを切り替えるだけで動く事が多い。

    作業前にPostgresのバックアップを取得することを強くお勧めします。

    https://hub.docker.com/r/redash/redash/tags/

    誰にどのデータを見せるかの制御したい

    様々なロールを持ってる人がredashを使っています。

    単純にKPIを追う人、センシティブな数値を扱う人と様々です。

    残念ながら現段階ではredashではオフィシャルに「見せる・見せない」を制御する機能はありません。

    データソースをもう一つつくり、そちらで制御するようにしました。

     

    https://qiita.com/S-T/items/c0e4bf3929771a30b720

    クエリが詰まる原因を知りたい

    クエリを実行したのに、結果が返ってこない。ということはよくあります。

    いわゆる「クエリが詰まる」という状況です。

    なぜ、どのような理由で詰まるのか。これについては @ariarijp さんのスライドが非常にわかりやすくまとまってます。

    詰まる箇所、つまり、全部。というわけです。

    クエリが詰まった。対処したい

    根本対応ではないのですが、前途したように、redisの中身をdeleteしてます。

    https://tsukada.sumito.jp/2018/08/25/redash-v5%E3%81%A7in-progress%E7%8A%B6%E6%85%8B%E3%81%AE%E3%82%BE%E3%83%B3%E3%83%93%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%82%92kill%E3%81%99%E3%82%8B/

    このような状況に陥った場合は、host側のswapも相当使用している可能性があるのでOSの再起動も合わせて行なってます。

    CLIで操作したい

    「redashのユーザーを作成してください」というのはredashを運用していてとても多いオペレーションです。

    GUIでもよいのですが、エンジニアにとってはCLIでやりたいこともあります。

     

    • ユーザー確認
      docker exec -it redash_server_1 ./manage.py users list
    • ユーザー作成
      docker exec -it redash_server_1 ./manage.py users create  tsukada@sumito.jp tsukada
    • ユーザーパスワード変更
      docker exec -it redash_server_1 ./manage.py users password tsukada@sumito.jp password
      
    • ユーザー削除
    docker exec -it redash_server_1 ./manage.py users delete tsukada@sumito.jp

    ただし、ユーザーに行動履歴があると、削除できません。その場合は履歴情報を削除してからCLIを実施する必要がありました。

    この点はVersion 5から改善され、GUIでユーザーをdisable化できるようになりました。

    そのため、現在弊社ではユーザーを削除するというオペレーションは行なっておりません。

    誰がどのクエリを実行したのか知りたい

    実は全てのクエリはredashのpostgresに保存されています。

    redashにログインし、 /admin に接続すると、管理者用のページが表示されます。

    但し、このページはadminのみアクセスが可能なページです。

    複数のデータソースを結合したい

    データソースAとデータソースBを結合することができます。joinのようなものです。

    Gunosyさんのブログに詳しい使い方が書いてあります。

    簡単にいうと、以下のようなクエリを書き、datasourceにQueryResultsを選択すると結合できます。

    select *
    from query_59 a
    join query_96 b
    where a.member_id = b.member_id;

    Dynamo DBをSQLで操作したい

    DynamoDBはDQLというSQLっぽいんだけど、SQLじゃないオリジナルの言語を使います。これが細かいところに手が届かなかったり、これが馴染みの無い人には辛い。

    QueryResultを経由させてSQLで操作できるようにします。

    https://tsukada.sumito.jp/2018/10/05/redash-query-result-dql/

     

    BigQueryを操作したい

    BigQueryはScan対象のカラムによって課金される。redashは実際に何行読み込み、容量は何kbyteだったのか表示してくれます。親切。

    redashのUserをgitで管理したい

    前途したuser listをCLIで表示させ、gitと連携しユーザの棚卸しを行なっている。

    ただし、Version 5でUserのenable/disable機能が組み込まれたが、CLIで確認することができなかった。一部昨日追記したところ、無事取り込んで戴けました。

    https://github.com/getredash/redash/pull/2951/files

    メリットは以下の通りです。

     

    redashにコントリビュートしたい

    CLIは穴場です。必要なものがまだ実装されておらず、且つ比較的簡単に実装できたりします。

    とはいえ、どのようにはじめたらいいかわからない、という方はぜひredashのdeveloper meeetupにお越しください。

    もくもくを経て、一人一人発表、フィードバックを得れる会です。その為参加人数も絞ってます。プルリク送ってコントリビュートしたい方、是非。

    会場は前回に引き続き、弊社レアジョブです。

    https://redash-meetup.connpass.com/event/110549/

  • redashのuserをgitで管理する

    redashのuserをgitで管理する

    はじめに

    [本記事はredash meetup 4.0.0で発表させていただいた内容に肉付けしたものです]

    redashはデータベースに接続できるツールなのでuserの管理がとても重要になる。
    userを定期的に棚卸しをし、メンテナンスしていくことはセキュリティを維持する上で必須だ。弊社では

    1. CLIでuser一覧を出す
    2. それをgitlabで管理
    3. gitlabに上がったということをchatworkで担当者に伝える
    4. 問題なければmerge
      merge日=最終棚卸し日

    というフローを採用し運用している。

    しかし、想定していた運用を採用するうえではソースを変更する必要があった。

    現在 version 5.0.2のCLI

    残念ながらこの画像からわかる通り、非常に貧弱である。

    version 5からuserをdisableする機能が導入されたが、userがenableなのか、disableなのかという情報がCLIからだとわからない。

    pull requestの作成

    機能としては存在しているのに、CLIで見れないとなると単純に表示させていないだけなのかもと察しソースを読んだ。

    Userのenableなのか、disableの情報を表示するメソッドを見つけた

    https://github.com/getredash/redash/blob/68272678b85ef4a6498543ef6a33a2071e607628/redash/models.py#L439

    おそらくGUIであればこの処理を叩いて画面に表示している。

    機能があるのであればCUIも同じように叩けばよいのでは?という仮説のもとファイルを変更した

    https://github.com/getredash/redash/pull/2951/files

    これでenableなのか、disableなのかがコマンドラインで確認できるようになった。

    自分の管理するredashはdockerで動いているので、linux上でviコマンドで編集し、docker cpコマンドでコンテナ内に転送することで変更を動いているredashに反映させた。

    OSSのソースに手を入れるというと相当な知識がないと変更できないかと思っていたが、progateでpython覚えた程度でも変更できた。

    最初テストケースを書かずにpushしたらCIでコケたので、恥ずかしながらそこでredashのテストコードの存在を知った。。

    せっかくなのでpull reqを出すと翌日mergeしてもらい、これがコントリビュートにつながった。

     

    その後CLI機能を拡張すべく2つpull requestを出させていただき、いずれも承認された。

    redashでユーザーを取得しGitLabへpushへ

    gitlab-cliの設定する必要があるので事前にセットアップする

    https://tsukada.sumito.jp/2018/10/17/python-gitlab/

    shellをcronで動かし、その中でpythonのスクリプトを動かす

    #!/bin/bash
    
    hostname=`uname -n`
    _roomid=123456789
    output=/tmp/$hostname
    
    cd ~/redash-user/
    
    git pull 
    nohup /usr/bin/docker exec -i redash_server_1 ./manage.py users list > ~/redash-user/$hostname &
    
    sleep 10;
    ps -ef | grep "./manage.py users list" | grep -v grep | awk '{print $2}' | xargs kill -9
    
    git checkout -b $hostname
    git add $hostname
    git commit -m $hostname
    git push origin $hostname
    
    python merge.py

    pythonはGitLabへpushするのに使っている。コードはこちら

    import os
    import gitlab
    
    hostname = '%s' % os.uname()[1]
    
    gl = gitlab.Gitlab('https://gitlab.sumito.com/', private_token='abcdefgggggggg')
    gl.auth()
    
    project = gl.projects.get(123, lazy=True)
    
    mr = project.mergerequests.create({'source_branch': (hostname),
                                       'target_branch': 'master',
                                       'title': (hostname) + ' user list'
                                       })
    
    mrs = project.mergerequests.list(state='opened', order_by='updated_at')[0]
    
    print(mrs.attributes['web_url'])

    以下のようにcronを仕込み月に一度listを更新し、GitLabにpushするようにしている。

    0 0 1 * * sh /root/redash-user/redashUsers.sh 1> /tmp/stdout.log 2> /tmp/stderr.log

    GitLabにMergeRequest上がっているのを取得、chat投げる処理

    これも同様にshellからpythonを動かすようにしている。

    #!/bin/bash
    
    cd /root/redash-user/
    hostname=`uname -n`
    _roomid=123456789
    
    tmp=$(/usr/bin/python ./chat.py)
    tmowl=`echo $tmp | grep git.sumito.com | wc -l`
    output=/tmp/gomi
    
    if [ $tmowl -eq 0 ] ; then
      exit
    else
    
    /usr/bin/cat << _EOT_ > /tmp/gomi
    [toall]
    [info]
    [title]latest redash account Please check it!!
    [/title] 
    `/usr/bin/python ./chat.py`
    [/info]
    _EOT_
      
    _body=`/usr/bin/cat $output`
    /usr/bin/curl -X POST -H "X-ChatWorkToken: 123456789" -d "body=${_body}" "https://api.chatwork.com/v2/rooms/${_roomid}/messages"
    
    fi
    

    pythonはこちら

    import os
    import gitlab
    
    hostname = '%s' % os.uname()[1]
    
    gl = gitlab.Gitlab('https://git.sumito.com/', private_token='123456789')
    gl.auth()
    
    # your project ID
    project = gl.projects.get(123, lazy=True)
    
    mrs = project.mergerequests.list(state='opened', order_by='updated_at')
    mr_url = [mr.attributes['web_url'] for mr in mrs]
    print("{}".format("\n ".join(mr_url)))

    アカウントの棚卸し

    以下のように表示される

    この状態ではmerge requestが発行された状態なので、

    管理者はこのリクエストを確認し、最新の状態を確認。問題なければmergeする

    当然gitなので最新merge日は更新され、この日が棚卸し完了日と位置づけすることにより、最終棚卸し日がいつだったのかわかるようにしている。

     

  • DQLで手の届きにくいところをredashでなんとかする

    DQLで手の届きにくいところをredashでなんとかする

    はじめに

    DynamoDBを操作するとき、DQLの操作が難しかったり、GroupByができなかったり。SQLでできないところができなかったりすることが多い。redashを使えばそれもなんとかなったりします。

    Query Resultsを活用

    redashにはQeury Resultsという機能があります(2018/10現在、ベータ版)。これは取得したクエリに対し、SQLを用いてデータを結合させたり、編集することができる機能です。

    一度DQLの結果をredashのQuery Resultsを経由させることで細かいところに手が届くようになります。

    Query Resultを指定し、redashで以下のようなクエリを書きます

    select *, sum(price)
    from query_123
    group by userID

    もちろんDQLのみならず、他の言語も似たようにQuery Resultをかえすことで編集可能です。