日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

redashで操作履歴とか見れる画面がなかなか見つからなくて困った話

redash便利ですよね。
色んなデータソースに対してクエリを発行できて、
それを可視化できて、共有できる。
とても便利。

redash.io

便利なので会社で使おうと思った時、
誰がどんなクエリ発行したのかとか見れたらいいなぁと思ってそんな画面を探していました。
結論から言うと /admin (e.g. https://redash.example.com/admin ) にありました。
こんな画面でした。

_人人人人人人_  
> bootstrap <  
 ̄Y^Y^Y^Y^Y ̄  

なんで困ったかというと、どこにもこの管理画面(?)へのリンクが無いんですね。
会社の先輩が「なんか /admin って打ったらあった」と言ってて、そのおかげで見つかりました。😇
(もしどこかにリンクがあれば誰か教えていただけると謎が判明して気持ちが晴れやかになるのとてもうれしいです。

まとめ

  • redashで /adminに行くと操作ログとかが見れる
  • bootstrap 便利ですよね!

最後にredashをdocker-composeで立てる検証用に作ったMakefileを置いておきます。

gist.github.com

ファイルの変更を検知してなんらかのコマンドを走らせるreflexが便利

ファイル変更があったらテストを流すとかいろんなライブラリありますが、
言語に依存しないやつないかなぁと思って探してたらgo製のものがありました。

github.com

go製なのでbinaryが配布されていればそれを持ってくればすぐ使えますね
そう思っている時期が私にはありました。
releasesみたらソースコードがおいてあってbinaryはありませんでした。
悲しい。

Release v0.1.0 · cespare/reflex · GitHub

まあIssueになってたり、READMEにもTODOと書いてあるのでそのうちbinary配布されるでしょう。
今回はとりあえずgo getでインストールして使ってみました。

GitHub - cespare/reflex: Run a command when files change

github.com

今回検証に使ったスクリプトこちらです。
cloneして go get github.com/cespare/reflex をすれば make test/watch, make test/watch/config, make test/watch/config/fancy あたりが動くはずです。

gist.github.com

1. あるファイルが更新されたらそのファイルに対してあるコマンドを走らせる例

$make test/watch
reflex -r '\.go$' -- go test {}
[00] --- FAIL: TestHoge (0.00s)
[00]   hoge_test.go:8: 1 + 1 != 2 !?
[00] FAIL
[00] FAIL  command-line-arguments  0.009s
[00] (error exit: exit status 1)
[00] ok    command-line-arguments  0.014s

別画面でhoge_test.goのテストを変えて、戻してみました。
いい感じに動きます

2. あるファイルにはあるコマンドを走らせて、違うファイルには他のコマンドを走らせる例

ある拡張子のものにはこのコマンドを走らせて、このディレクトリにあるものにはこのコマンドを走らせたい。
みたいなときにはconfigにまとめて使うと良さそうです。

$make test/watch/config
reflex -c reflex.conf
[01] No syntax errors detected in hoge.php
[00] ok    _/Users/a-tanaka/hogehoge   0.008s
[01] No syntax errors detected in hoge.php
[01] PHP Parse error:  syntax error, unexpected '"', expecting ',' or ';' in hoge.php on line 3
[01]
[01] Parse error: syntax error, unexpected '"', expecting ',' or ';' in hoge.php on line 3
[01] Errors parsing hoge.php
[01] (error exit: exit status 255)
[01] No syntax errors detected in hoge.php
[00] --- FAIL: TestHoge (0.00s)
[00]   hoge_test.go:8: 1 + 1 != 2 !?
[00] FAIL
[00] FAIL  _/Users/a-tanaka/hogehoge   0.007s
[00] (error exit: exit status 1)
[00] ok    _/Users/a-tanaka/hogehoge   0.008s

このブログ上だとシンタックスハイライトが効いてますが、 ターミナル上だと殺風景でちょっと見づらいなと思ったらいい感じのオプションがありました。 

-d, –decoration=“plain”: How to decorate command output. Choices: none, plain, fancy.

_人人人人_
> fancy <
 ̄Y^Y^Y ̄

なんかおしゃれになりそう。

Before

f:id:arata3da4:20170622201242p:plain

After

f:id:arata3da4:20170622201245p:plain

なんかおしゃれになりました。

まとめ

  • reflexファイル変更があったときに任意のコマンドを実行できて便利
  • まだbinaryはないけどそのうちできたらgoへの依存もなく使えるので便利になりそう
  • fancy

今更ながらRetryするGolangのpackage書いてみた

何番煎じかわからないですが、かいてみました。
呼び出し方がretry.Retryってなってなんかびみょ・・・

github.com

使い方

retry.Retryの第三引数の実装にリトライがありえる処理を書く感じです。
errorが返った場合にはretry.Retryの第一引数に与えた回数分だけリトライします。
リトライの間の待ち時間は第二引数で設定できます。
第二引数の関数は、今のリトライ回数と前回の結果を受け取って待ち時間を返す関数にする必要があります。
retry.Retryの返り値は、第三引数に与えた関数の返り値と一致します。
第一引数分リトライをしてもerrorが返った場合はerrorが返ります。

main.go

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/ara-ta3/retry"
)

func main() {
    c := someClient{
        n: 0,
    }
    // retry.Retry returns the return values of "func" at third args
    r, err := retry.Retry(
        10,
        func(n int, r interface{}) time.Duration {
            // waiting time
            return 0 * time.Second
        },
        func() (interface{}, error) {
            // your codes
            // if this returns error, this will retry this "func"
            return c.DoSomething()
        },
    )
    if err != nil {
        log.Fatalln(err)
    }

    res, ok := r.(*result)

    if !ok {
        log.Fatalf("result cannot be cast to Result struct. r: %+v", r)
    }

    fmt.Printf("%+v\n", res)
}

type someClient struct {
    n int
}

type result struct {
    Message string
}

func (c *someClient) DoSomething() (*result, error) {
    if c.n >= 5 {
        return &result{
            Message: fmt.Sprintf("some message. n: %d", c.n),
        }, nil
    }
    c.n++
    fmt.Printf("count: %d\n", c.n)
    return nil, fmt.Errorf("return error for retry")
}

これを実行すると下記のような感じになります。
待ち時間は0秒にしているので一瞬で終わります。

$time go run main.go
count: 1
count: 2
count: 3
count: 4
count: 5
&{Message:some message. n: 5}
go run main.go  0.14s user 0.08s system 98% cpu 0.231 total

感想

  • retry色んな所でやりたくなったりするので、書いてみました。
  • 便利なので使っていきたい。

GolangのsqlxでIN句が使いたかったので調べたメモ

Golangでバッチを最近書いてるんですが、
sqlxを使っていて、
IN句のprepared statmentどうやって使うんだろうと思ったので調べたときのメモです。

準備

とても適当なテーブルを用意します。
idとnameをカラムにもつhogeというテーブルです。
3件適当なデータを突っ込んでおきます。

((none))> use test;
Database changed
(test)> create table hoge (id int auto_increment, name varchar(255), primary key (id));
Query OK, 0 rows affected (0.03 sec)

(test)> insert into hoge (name) values ("hoge");
Query OK, 1 row affected (0.01 sec)

(test)> insert into hoge (name) values ("fuga");
Query OK, 1 row affected (0.00 sec)

(test)> insert into hoge (name) values ("piyo");
Query OK, 1 row affected (0.00 sec)

(test)> select * from hoge;
+----+------+
| id | name |
+----+------+
|  1 | hoge |
|  2 | fuga |
|  3 | piyo |
+----+------+
3 rows in set (0.00 sec)

書いたコード

idが2, 3のレコードを取ってきてstructにbindさせています。
structにbindさせるやつはこのへんで試したりしました。

golangでSQLを投げて返ってきた結果をstructにbindしたい - 日頃の行い

書いたコードはこんな感じです。
この辺のドキュメントを参考にしました。

Illustrated Guide to SQLX

gist.github.com

動いたっぽい。

感想

  • テーブルからIN句を使ってデータを取ってstructにbindできました。
  • IN句も使えそう。
  • sqlx.Inを使うと第二引数に与えたsliceの長さ分だけ ? を増やしたクエリを返してくれるみたいですね。
  • そのクエリを利用してSelectやらRebindやらすればいいみたいです。便利。

こちらもおすすめ

arata.hatenadiary.com