下級エンジニアの綴

新しく発見したことを綴っていこうと思っています。夢はでっかく上級エンジニアになることです。

re:dashユーザ追加でハマったのでメモ

re:dashをdockerで立てて運用した時に新規ユーザーを作成しようとしましたが、少し時間がかかったので手順をまとめました。

GUIで行う場合はメールサーバを立てないとメールが送られてこないので、ユーザーを作成しても仮パスワードが送られてきません。

なのでユーザを追加する時はメールサーバか直接ユーザ作成のコマンドを叩きましょう!

今回はメールサーバをを立てずにCLIで実行する時の手順をまとめました。

  • redashがあるフォルダに移動します
$ cd /opt/docker/redash/
  • re:dashはdockerで立てているのでプロセスを確認してください
$ docker ps
a460fb29f959        redash/nginx:latest    "nginx -g 'daemon off"   5 months ago        Up 5 months         0.0.0.0:80->80/tcp, 443/tcp        redash_redash-nginx_2
922aae8a262d        redash/redash:latest   "supervisord -c /opt/"   5 months ago        Up 5 months         0.0.0.0:6000->6000/tcp, 9002/tcp   redash_redash_2
2674c781bda9        postgres:9.3           "/docker-entrypoint.s"   5 months ago        Up 5 months         6543/tcp                           redash_postgres_2
c6e145400d1b        redis:2.8              "docker-entrypoint.sh"   5 months ago        Up 5 months         7379/tcp                           redash_redis_2
  • 次のコマンドを実行してください docker exec -it redash_redash_2 ./manage.py users create [name] [email]
  • 最終行でパスワードを入力できるので設定すると登録完了になります。
$ docker exec -it redash_redash_2 ./manage.py users create test test@gmail.com
[2017-07-06 12:18:44,544][PID:2891][INFO][requests.packages.urllib3.connectionpool] Starting new HTTP connection (1): metadata.google.internal
[2017-07-06 12:18:44,547][PID:2891][WARNING][redash.query_runner] BigQueryGCE query runner enabled but not supported, not registering. Either disable or install missing dependencies.
Creating user (test@gmail.com, test) in organization default...
Admin: False
Login with Google Auth: False

Password:

勉強になりました。

rubyのeachメソッドについて少し調べてみた

結論を先に述べるとよくわからなかったです。 とりあえず、調べた内容を残しておきました。

hoge = [{0=> 'aaaa'}, {1=> 'bbb'}, {2=> 'ccc'}]

hoge.each.with_index do |a, index|
  p a.object_id, hoge[index].object_id
end

p hoge
69822855751840
69822855751840
69822855751800
69822855751800
69822855751760
69822855751760
 [{0=>"aaaa"}, {1=>"bbb"}, {2=>"ccc"}] 

こう見ると、a.object_id, hoge[index].object_idは同じオブジェクトのように見える。

hoge.each.with_index do |a, index|
  a = {(index) => 'ddddddd'}
end

p hoge
 [{0=>"aaaa"}, {1=>"bbb"}, {2=>"ccc"}] 
hoge.each.with_index do |a, index|
  a[index] = 'ddddddd'
end

p hoge
[{0=>"ddddddd"}, {1=>"ddddddd"}, {2=>"ddddddd"}] 

↑2つの挙動は同じだと思うのだが、実際は違う・・・ 謎だ・・・

[{0=>{}}, {1=>{}}, {2=>{}}]  
hoge.each.with_index do |a, index|
  p a, index, hoge
  hoge.delete a
end

p hoge
{0=>{}}
0
[{0=>{}}, {1=>{}}, {2=>{}}]
{2=>{}}       
1         
[{1=>{}}, {2=>{}}]
[{1=>{}}]               

deleteメソッドを使うとこの用にレシーバを書き変えることが出来た。

rubyソースコードまでは読めていないので、本日はここまでにさせていただきます。

とりあえず、コメント書いとけば良いと思っているエンジニアを減らしたい

どうもやんてらです。

今回は技術的な記事ではなくて個人的に思っていることを書いていこうと思っています。 (内容は愚痴になりますので不愉快だと思われる方はブラウザバックをお願いします。)

今回取り上げた内容は「コメント」です。

ソースコードの中にコメントを書くという文化を否定したいわけではないのですが、メソッド名や変数名を特に考えずにコメントで補えば良いと思っているエンジニアに一言申し上げたくて記事にしました。

※サンプルのコードはrubyになります

def show_cost_per_click(ad)
   ad_value(ad)
end

# 有効なad判別したい
def ad_value(ad)
  ad.cpc if ad.present?
end

↑のソースを読んで思ったことが何個かありました。

先ずはじめに、adの値メソッドの「戻り値が何なのか?」というのと「このメソッドでやりたいことって何?」ということでした。 コメントには有効なadの判別をしたいと書いてありますが、「本当にこのメソッド名で良いのか?」って私は思いました。

コメントを残す前に適切なメソッド名をつけて欲しいなと個人的には思っているので、 この場合ですと、available_adみたいなメソッドであれば凄くわかりやすかったです。この場合であればコメントも別に書かなくても英語を翻訳するだけでやりたいことは伝わるかなと思います。

個人的な良い例

def show_cost_per_click(ad)
  ad.cpc if available_click?(ad)
end

def available_ad?(ad)
  ad.present?
end

↑のような状態で補足したい場合も、もちろんあると思います。その時にこそコメントを残してくれればありがたいと思います。 しかし、そういう場合以外でコメントで補おうとしてしまうと次に改修する人のコストになってしまうので避けて欲しいなと思います。

個人的には変数名やメソッド名に悩めば悩むほどスッキリとしたコードになることが多いので、もっと変数名とメソッド名に意味を持して欲しいなと思いました。

(コードを書き始めて日が浅い人やリーダブルコードを読んだことのない人は一度読んでみて頂きたいです。

長文でしたが、最期までお付合い頂きありがとうございました。

rubyのnilを0にしたいときに調べたのでメモ

数値を扱っているときにnilを使いたくないので、調べたらいい感じに行けそうだったのでメモ。

nil.nil?       # true
nil.to_i       # 0
nil.to_i.nil?  # false
nil.to_s       # ""
nil.to_s.nil?  # false
nil.to_s.empty # true

rubyって面白いですね。

Wunderlistに設定しているタスクを毎日(平日限定)slackに通知する流れを作ってみた

slackにタスクを毎日通知してくれるいい感じのツールが見つからなかったので、自作してみました。

必要なもの

手順

※wunderlistにタスクが登録されている前提で進めていきます

node.jsのインストール
yum install epel-release
yum install nodejs npm
yum install gcc gcc-c++
wunderlineのインストール
npm install -g wunderline
rubyのインストール

下記サイトを参考にしてください(手抜きで大変申し訳ないですmm)

CentOS に Ruby をインストールする - kzy52's blog

実際のコード
#!/usr/bin/env ruby
require 'slack'
require 'json'

### confの内容
※confは下記のように定義しています
######################################
slack_token,slack_token
wunderlist_token,wunderlist_token
client_id,client_id
channel,channel
wunder_list_url,wunder_list_url
######################################

- slack_token          # slackに通知するためのtoken
- wunderlist_token     # wunderlistに通知するためのtoken
- client_id            # wunderlistのclient_id
- channel               # 通知したいslackのチャンネル
- wunder_list_url      # wunderlistで叩きたいapiのURL


conf_file_path = '/home/[ユーザー名]/slack_bots/schedule_conf.txt' # cronを実行するユーザーがfile openするので絶対パスがおすすめ

### confの取得
datas = []
begin
  File.open(conf_file_path) do |file|
    file.each_line do |line|
      datas.push(line.chomp!)
    end
  end
end

### 取得したconfをhash化する
scheduler = {}
datas.each do |data|
  ary = data.split(',')
  scheduler[ary.first] = ary.last
end

### wunserlistからjson形式でパラメータを取得
result = `curl -H "X-Access-Token: #{scheduler["wunderlist_token"]}" -H "X-Client-ID: #{scheduler["client_id"]}" #{scheduler["wunderlist_url"]}`

result = JSON.parse(result)

### slackで表示するために整形
tasks = []
result.each do |r|
  tasks.push(r["title"])
end

task_list = tasks.join("\n")

Slack.configure do |config|
  config.token = scheduler["slack_token"]
end

line = "---------------------------\n"
text = case Time.now.hour
       when 11 then "#{line} today tasks confirm \n #{line} #{task_list}"
       else
         'Error!!'
       end

Slack.chat_postMessage(text: text, channel: scheduler["channel"], link_names: true, username: 'scheduler')
cronに登録
$ cat /home/[ユーザー名]/slack_bots/config/schedule.rb
every '30 23 * * 1-5' do
  command '/home/[ユーザー名]/slack_bots/time_signal.rb'
end

$ bundle exec whenever --update-crontab

結果

出来たー!! 表示のさせかたはもう少し修正が必要ですが、とりあえず欲しい物は作れました。

気になってるところ

  • とりあえず動けば良い程度のコードになっているので、もっときれいに書き直したいですね。(curlを叩くところとか)
  • WunderlistのAPIを叩くためのtokenの発行の仕方が結構わかりにくかったので、もしかするとそこで結構詰まるかもしれないです・・・

参考リンク

タスク管理ツール WunderlistのAPIで遊んでみた - Qiita

Wunderlist をコマンドラインから操作する Wunderline - WebDelog

10分コーディング! Rubyでつくる Slack時報 | Money Forward Engineers' Blog

linuxのfind -mtimeの挙動で失敗したのでメモ

今回はlinuxのfindコマンドのmtimeオプションで失敗したのでメモするために書きました。

今回失敗したこととしては、ファイルの削除cronを回しているときにfindコマンドを使って-mtimeオプションで時間を指定して削除処理をおこなっていました。 しかし、消しては行けないフォルダまで消してしまったので色んな問題が発生しました。

本題

  • これが初期状態です。
[vagrant@localhost test]$ ll -a memo/
total 8
drwxrwxr-x 2 vagrant vagrant 4096 Feb  2  2002 .
drwxrwxr-x 3 vagrant vagrant 4096 Jan 14 18:50 ..
-rw-rw-r-- 1 vagrant vagrant    0 Jan 14 18:45 aaaa.txt
-rw-rw-r-- 1 vagrant vagrant    0 Jan 14 18:45 bbb.txt
  • 削除処理を実行
[vagrant@localhost test]$ find memo/ -mtime -1 | xargs rm -rf
  • 削除結果
[vagrant@localhost test]$ ls -a memo/
.  ..

ここまでは想定通りの結果だったので問題なかったのですが、問題は次の処理になります。

[vagrant@localhost test]$ ls -a memo/
.  ..
[vagrant@localhost test]$ ll -a
total 12
drwxrwxr-x  3 vagrant vagrant 4096 Jan 14 19:05 .
drwx------. 5 vagrant vagrant 4096 Jan 14 18:50 ..
drwxrwxr-x  2 vagrant vagrant 4096 Feb  2  2002 memo
  • memoフォルダが空になっている状態で下記の処理を実行すると
[vagrant@localhost test]$ find memo/ -mtime -1 | xargs rm -rf
[vagrant@localhost test]$ ll -a
total 8
drwxrwxr-x  2 vagrant vagrant 4096 Jan 14 19:01 .
drwx------. 5 vagrant vagrant 4096 Jan 14 18:50 ..

なんと!!! memoフォルダまで消えてしまいました・・・・orz

補足

補足ですが上記のケースを回避するには

フォルダを指定するときに*を指定してやれば・・・

[vagrant@localhost test]$ find memo/* -mtime -1 | xargs rm -rf
find: `memo/*': No such file or directory
[vagrant@localhost test]$ ll -a
total 12
drwxrwxr-x  3 vagrant vagrant 4096 Jan 14 19:05 .
drwx------. 5 vagrant vagrant 4096 Jan 14 18:50 ..
drwxrwxr-x  2 vagrant vagrant 4096 Feb  2  2002 memo

この通りフォルダは削除されずに済みます!

いやー、知らない事がいっぱいあると再度実感したました。

resqueのworkerがoverviewで表示されるのにサーバ側ではプロセスが存在しないから調べてみた

resqueのoverviewでよく分からないworkerが存在していたので、killしようと奮闘していた話です。 ドキュメント残すついでに書いてみました。

発見時

f:id:yanterakun:20160710155256p:plain

サーバでプロセスを確認

ps aux | grep resque

f:id:yanterakun:20160710154420p:plain

おらんやん!!

なんやこのプロセス・・・・

調べてもよく分からなかったので、友人に相談・・・

「redisにkey残ってるだけじゃね?」と言われたので、

redisの中を見てみると・・・・!?

redis-cli
keys keys resque*

f:id:yanterakun:20160710162037p:plain

おったー!!!

結論

redisのkeyに残っており、それが表示されてたみたいです。

まだまだredisとresqueについての知識(ggr力も)がまだまだ足りてないなと反省しました。

教えてくれた友人に感謝してますmm