This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

2014/11/28 誰にでもできる!ビッグデータ分析基盤の構築術 @IDCフロンティア

Last updated at Posted at 2014-11-13

はじめに

本日は平日の午前中というなかお越し頂き有り難うございます。
本日のハンズオンセミナーが皆さんにとって有意義になるように努力しますので、疑問点・不明点などありましたらどしどし聞いてください。

本日のGoalとやること

Goal

Yahoo!ビッグデータインサイト(以下YBI)を利用して簡単にサーバーログを取得、集計ができることを確認すること。

やること - 流れ

本日やることは以下となります。

  • Step1: YBIのアカウント登録(無料)
  • Step2: IDCFクラウドのアカウント登録(本日分は少なくとも無料)
  • Step3: VM作成
  • Step4: ネットワーク設定
  • Step5: SSH接続作業
  • Step6: Webサーバー(Nginx)インストール
  • Step7: TD-CLI(Command Line Tool)インストール
  • Step8: YBIの設定(DB作成/Table作成)
  • Step9: td-agentのインストール
  • Step10: td-agent設定
  • Step11: YBIへのデータアップロード
  • Step12: YBIでの集計処理

やること - イメージ

以下本日やることのイメージ図となります。

summary.png

Step1: YBIのアカウント登録

YBIサインアップページにアクセスして必要事項を入力して、Sign Upボタンを押下します。
必要事項は以下になります。

  • 氏名
  • 会社名
  • 電話番号
  • メールアドレス
  • パスワード

ybi_signup_campaign.png

自動で課金されるということはありませんのでご安心ください。

Step2: IDCFクラウドのアカウント登録

Step2-1: IDCFクラウドのコンソールにアクセス

IDCFクラウドサインアップページにアクセスして
新規会員登録ボタンを押下します。

console_signup.png

Step2-2: ログイン情報登録

次に以下の必要事項を入力して、利用規約に同意するチェックボックスにチェックを入れ、電話認証へ進むボタンを押下します。

  • アカウントID
  • メールアドレス
  • パスワード

console_signup_2.png

Step2-3: 電話認証

以下必要事項を入力して電話確認ボタンを押下してください。

console_signup_3_tel.png

そうすると英語で電話がかかってきて、認証コードとなる4桁の数字を教えてくれます。
その4桁の認証コードを入力して、認証するボタンを押下してください。

console_signup_4_tel.png

Step2-4: メール認証

認証が通ればStep2-2で登録したメールアドレスnoreply@idc.jpから以下のようなメールが届いているはずです。
console_signup_5_mail.png

メール本文中のリンクをクリックすることでメール認証が完了し、認証作業が終了となります。

console_signup_6_finished.png

VMを作成するためにはアカウント情報登録、支払い方法を登録する必要がありますのでログイン画面へボタンを押下して、コンソール画面を表示させてください。

Step2-5: アカウント情報登録

以下の必須入力項目を入力して、基本情報を保存するボタンを押下してください。

  • 会社名
  • 郵便番号
  • 都道府県
  • 住所

console_input_account.png

Step2-6: 支払い情報登録

アカウント情報登録が完了すると、画面下に以下の支払い方法登録フォームが表示されます。
クレジットカード情報を入力して、クレジットカードを登録するボタンを押下してください。

console_input_credit.png

Step2-7: クーポンコード登録

このままではVM作成したときに課金してしまいますので本日配布するクーポンコードを登録してあげます。
本日発行させて頂くクーポンは5000円分となります。ただし有効期間は6ヶ月となるので、以下のいずれかの条件が満たされた場合に課金されてしまいますのでご注意ください。

  • 5000円分のクーポンを使い切る(light.S1の場合だと10台 * 1ヶ月で使い切られます。)
  • 6ヶ月経過した場合。
当日口答で説明します!

Step3: VM作成

さてこれでVMを無料で作成できる環境が整いました。

Step3-1: コンソール画面にログイン

IDCFクラウドコンソールにアクセスしてログインします。

Step3-2: VM作成

ホーム画面の仮想マシン作成ボタンを押下します。
console_vm_create_1.png

Step3-3: インスタンスタイプの設定

light.S1を選択してください。
vm_create_type.png

Step3-4: OS選択

Linuxならなんでもよいのですが・・・この資料ではUbuntu14.04を選択しておきます。
vm_create_image.png

Step3-5: Volume設定

デフォルトでROOTディスクで15GBあるのでこのままとします。

vm_create_volume.png

Step3-6: SSH-Key作成

ご自身のsshの公開キーをアップロードすべきなのですが、今回は環境を揃えるために新たにSSH-keyを作成する手順となっております。
ご容赦ください。

名前はybi_YYYYmmddのような適当な名前を入力しておいてください。名前入力後作成ボタンを押下します。

vm_create_ssh_create.png

作成されると以下のように秘密キーが表示されるので、コピーして適当なファイル名(~/.ybi_ssh)でローカルに保存してください。

vm_create_ssh_create_2.png

最後に改行が入らないように注意してください。

~/.ybi_ssh
$ cat ~/.ybi_ssh
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCT/J5Vg2DhkMQHph74ooCkznglFrQu5TmZ0qDLK5SnrhGfvpFF
1u6TpObRkv5ycYm5gSPl9jDRg4kSVoX/ueoRptf253fKIIE03ybuZvWjYH4ES0F3
5cpMENXP2VRWN00j51E16bQCr7Ko6zKQMexrgvzbXXnRGtRON2D77RcusQIDAQAB
AoGAZXmk7MhQx3uoIAKWXDG5+silc/E0jq+aJtNadNamcbCX3y0imnw+TjmWGQEt
vzYBlZVrE0YUxaXneQ6hhfBrArKaTwr2WtCRBAFxao/mDqoz/kgeS6T/GS4KSuqd
RnscIeQHOThxBi+ezCqM0FC8OJ+Vlsd5ig+U2NWv2p70800CQQDHv/xZVKMIPV6J
yCkzC6G4oSFe5T8IgVj3yyrGK9lMLQu+QI+Jfs0Qhndl6vonOPdnwJHhZeNptYii
DxQPwMrvAkEAvakENxLg9tmBuYxjhW3XBVLJUnOdH4JwVNGyMF/+xUA0x34qdCIZ
dbIZZLwpjWsGWF7M/ZamuQn8+tLtL7IgXwJBAKt0CimvMUU4T/ZZ/asX99dfTyKC
CanGRNRk6jExoBH3tFW4Wrw9P81IbiHoIJIcHphKvazH5PxuWnooESM4a7cCQQCw
8neUSnDI3bVCP9C6M/hgZxSdcHAvbasP93Sf3W/86CJV3UgOgaHvRPKcIVFDN477
87adAWkbSk5UVWYlEbNRAkA5SJKAWDlp79AWTCP9CYCBGh5upwt5UgrZ3sisgrwF
+gScruHTzHVTjJ34Xb71uPokAA0C3oGxpcDQAp+E7WnR
-----END RSA PRIVATE KEY-----
$ 

Step3-7: 仮想マシン名設定

以下適当なマシン名とグループ名を入力してください。
ここではybi-handsonybi_20141112と入力しています。
入力後確認画面へボタンを押下します。

console_vm_create_1.png

Step3-8: 作成

確認画面で設定した値に誤りが無ければ、作成ボタンを押下してVMを作成します。

vm_create_confirm.png

作成したVMがRunning状態になったらVMの準備が整ったことになります。

vm_create_running.png

Step4: ネットワーク設定

VMを作成できましたが、今の状態ではクラウド内のローカル環境では導通可能となりますが、インターネット経由ではまだ接続することができません。
ここではインターネット経由で接続できるように以下の設定を行います。

  • SSHのファイアーウォール設定
  • SSHのポートフォワーディング設定
  • HTTPのファイアーウォール設定
  • HTTPのポートフォワーディング設定

Step4-1: パブリックIP表示

まずはパブリックIPアドレスを取得します。
といっても初回VM作成時には既にパブリックIPアドレスが発行されています。

IDCFクラウドコンソールのサイドメニュにあるIPアドレスをクリックしてIPアドレス画面を表示します。

config_get_ip.png

そうすると、IPアドレス名network1というIPアドレスが表示されるはずです。

Step4-2: SSHファイアーウォール設定

network1をクリックしてネットワーク設定画面を開きます。

config_get_ip_6.png

ネットワーク設定画面でファイアーウォールメニュをクリックしてファイアーウォール設定画面を開きます。
以下必要事項を入力して+ボタンを押下します。
必要事項は以下となります。

  • コメント: ybi.ssh
  • ソースCIDR: Any
  • タイプ: CustomTCP
  • ポートレンジ: 22

config_get_ip_ssh_firewall.png

これでnetwork1のポート22にアクセスできるようになりました。

Step4-3: SSHポートフォワーディング設定

次にnetwork1ポートフォワーディングメニュを選択して、設定画面を開いてください。

config_get_ip_ssh_portfowarding_1.png

ポートフォワーディング設定画面で以下必要事項を入力して+ボタンを押下します。

  • コメント: ybi.ssh
  • プライベートポート: SSH
  • パブリックポート: 22
  • 仮想マシン: ${Step3で作成したVM名}

これでインターネット経由でnetwork1経由で作成したVMのポート22にアクセスできるようになりました。

Step4-4: HTTPファイアーウォール設定

Step4-2: SSHファイアーウォール設定の箇所をSSHHTTPに、2280に読み替えて実施してください。

Step4-5: HTTPポートフォワーディング設定

Step4-3: SSHポートフォワーディング設定の箇所をSSHHTTPに、2280に読み替えて実施してください。

さてこれでネットワーク設定が完了しましたのでSSH経由で作業できるようになりました!!

Step5: SSH接続作業

本来なら難しい作業ではないのですが、今回はIDCFクラウドで新たにSSH-Keyを作成してそれを用いてSSHログインすることになります。
それぞれの環境に合わせて作成したVMにSSHログインしてください。

Step5 Case1: MacOSX, Linuxの場合

以下のコマンドを実行して、SSHログインします。

$ chmod 600 ~/.ybi_ssh # 読み込み書き取り権限のみとします。
$ ssh -i ~/.ybi_ssh root@${ip_address}
The authenticity of host '${ip_address} (xxx.xxx.xxx.xxx)' can't be established.
RSA key fingerprint is 57:84:18:2b:ff:e0:80:09:af:fd:d7:c0:ea:d6:ec:8b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '${ip_address}' (RSA) to the list of known hosts.
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-33-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

root@ybi-handson:~# 

${ip_address}にはnetwork1のIPアドレスを入力してください。

Step5 Case1: Windowsの場合

Step5-1: SSHクライアントツールのインストール

SSHクライアントツールがローカル環境にない場合は、多分Windowsでは最も一般的である(と私が勝手に思っているだけかもしれませんが)、
TeraTermにアクセスして、teraterm-4.84.exeをダウンロードしてください。

teraterm_download.png

あとはダウンロードファイルを実行すればインストールできるはずです!

Step5-2: SSHログイン

Step5-2-1: IP指定

まずはTeraTermを起動します。

teraterm.login_1.png

そしてホストにnetwork1に設定されているIPアドレスを入力してOKボタンを押下します。

Step5-2-2: known_hostsに追加

セキュリティ警告ポップアップが表示されますが、無視して続行ボタンを押下してください。
teraterm.login_2.png

Step5-2-3: 秘密鍵設定

ユーザ名にrootと設定して、秘密鍵ボタンを押下して先ほど作成した.ybi_sshファイルを選択します。

teraterm.login_3.png

Step5-2-4: ログイン

選択後OKボタンを押下してSSHログインします。

teraterm.login_4.png

正常ログイン後には以下のような画面が表示されるはずです。

teraterm.login_5.png

Step6: Webサーバー(Nginx)インストール

さてここからようやくLinuxコマンドを使うことが出来ます!
長かったですね^^;

Step6-1: SSH-Login

SSHクライアントでVMにログインしていない方はSSHログインしてください。

Step6-2: Nginxインストール

以下のコマンドでパッケージインストールします。

install_nginx
# apt-get install nginx
# nginx -v
nginx version: nginx/1.4.6 (Ubuntu)
#

Step6-3: Nginxの起動

インストール後に自動起動されています。。。

status
# service nginx status
 * nginx is running
#

Step6-4: アクセスしてみる。

お使いのWebブラウザでnetwork1のIPアドレスにアクセスしてみてください。
以下のような画面が表示されるはずです。

welcome_nginx.png

Step7: TD-CLI(Command Line Tool)インストール

さて必須ではないのですが、せっかくですのでYBIのコマンドラインツールであるTD-CLIをインストールしておきます。

Step7-1: 必要パッケージのインストール

デフォルトのままですとMakefileを作成するために必要なパッケージがありませんので以下のコマンドでパッケージをインストールします。
必要なパッケージは以下となります。

  • ruby-dev: rubyの開発用パッケージ
  • make: ビルドに利用するmakeパッケージ
install_ruby-dev
# apt-get update
# apt-get install make ruby-dev
#

Step7-2: TD-CLIのインストール

TD-CLIはRubyGemsのパッケージですのでgemコマンドでインストールします。

td_install
# ruby --version
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
# # TD-CLIはruby1.9以上を推奨しています。
# gem install td
#
# td --version
0.11.5
# 

Step7-3: エンドポイント設定

エンドポイントを設定します。
適当なファイル、~/.bash_profileなどに以下の記述を追加してください。~/.bash_profileはインストール直後には存在しないのでvimなどのテキストエディタで作成してください。

~/.bash_profile
export TD_API_SERVER=https://ybi.jp-east.idcfcloud.com

正常にファイル保存が行われている場合は以下のように表示されるはずです。

ファイル正常性確認
# cat ~/.bash_profile
export TD_API_SERVER=https://ybi.jp-east.idcfcloud.com
# source ~/.bash_profile
# env | grep TD_API_SERVER
TD_API_SERVER=https://ybi.jp-east.idcfcloud.com
#

Step7-4: ログインしてみる

以下のコマンドでログインすることができます。

ybi_login
# td account -f
Enter your Treasure Data credentials.
Email: ${ybi_email}
Password (typing will be hidden): ${ybi_password}
Authenticated successfully.
Use 'td db:create <db_name>' to create a database.
# 

さてこれでTD-CLIの準備が整いました!

Step8: YBIの設定(DB作成/Table作成、WriteOnlyKey取得)

ここではnginxのログを入れるための箱であるDB/Tableを作成します。

Step8-1: DB作成/Table作成

以下のコマンドで簡単にDBとTableを作成することができます。
ybi_handson_20141128がDB名、www_accessがTable名となります。

db_table_create
# td db:create ybi_handson_20141128 # DB作成
Database 'ybi_handson_20141128' is created.
Use 'td table:create ybi_handson_20141128 <table_name>' to create a table.
# td table:create ybi_handson_20141128 www_access # Table作成
Table 'ybi_handson_20141128.www_access' is created.
# td table:show ybi_handson_20141128 www_access # Table情報表示
Name        : ybi_handson_20141128.www_access
Type        : log
Count       : 0
Schema      : (
)
#

Step8-2: WriteOnlyKeyの取得

Step8-2-1: YBIコンソールにアクセス

まずはYBIサインインにアクセスしてログインします。
そしてEmailPasswordを入力してログインしてください。

signin_1.png

Step8-2-2: Profile画面を表示

コンソール画面のヘッダメニュのアカウント名をクリックしてください。
そうするとプルダウンでメニュが表示されますのでそこでMy Profileを選択してください。

console_my_profile.png

Step8-2-3: API-Keyの取得

API Keysカードでパスワードを入力してShow Keysボタンを押下してください。

console_getapi1.png

そうするとWrite-Only API keysが表示されますのでその値を後で利用しますので記録しておいてください。
ない場合は、Generate Newボタンを押下して新たに作成してください。

console_getapi4.png

次はtd-agentのインストールです。

Step9: td-agentのインストール

さて最近Docker管理ツールのKubernetesで標準のログ収集ツールになったことでも話題のFluentdで、その安定版となるのがこのtd-agentというものになります。

Step9-1: td-agentのインストール

以下のコマンドでtd-agentをインストールします。

td-agent
# curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh
# td-agent --version
td-agent 0.10.55
# /etc/init.d/td-agent status
 * ruby is not running
# # rubyになっているががが。。。正しいんですかね^^;

Step10: td-agent設定

さて、ここからtd-agentでとnginxのログを監視して、YBIにインポートする設定を行っていきます。

td-agentの設定ファイルは/etc/td-agent/td-agent.confとなります。

Step10-1: ファイルのバックアップ

まずデフォルトの設定ファイルをバックアップしておきます。
設定ファイルのパスは/etc/td-agent/td-agent.confとなります。

file_backup
# cp -p /etc/td-agent/td-agent.conf /etc/td-agent/td-agent.conf.org
# ls -1 /etc/td-agent/td-agent.conf*
/etc/td-agent/td-agent.conf
/etc/td-agent/td-agent.conf.org
#

Step10-2: ファイル編集

ここでは余分な設定はいりませんので、一度設定ファイルを削除して再作成する手順とします。
まずは以下のコマンドで既存の設定ファイルを削除します。

ファイル削除
# rm /etc/td-agent/td-agent.conf

そしてvimなどのテキストエディタで以下のようにファイルを編集してください。

/etc/td-agent/td-agent.conf
# Tailing the Nginx Log
<source>
  type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx-access.pos
  tag td.ybi_handson_20141128.www_access
  format nginx
</source>

# Treasure Data Input and Output
<match td.*.*>
  type tdlog
  apikey ${your_api_key} # Step8-2で取得したAPI-Key。
  auto_create_table
  buffer_type file
  buffer_path /var/log/td-agent/buffer/td
  endpoint https://ybi.jp-east.idcfcloud.com
  flush_interval 10s
  use_ssl true
</match>

上記の意味は以下となります。

  • sourceタグ
source
type: 監視方法を指定。今回はtailと指定して、新規に出力されるログを監視します。
path: 監視対象のパスを指定します。
pos_file: 監視対象のログの最後に読み込んだ位置を保持するファイル。
tag: 後述するmatchに紐付けるためのイベント名。td.${db_name}.${table_name}と指定します。今回は"td.ybi_handson_20141128.www_access"としています。
format: ログのフォーマット、td-agentではデフォルトでnginxのフォーマットをサポートしています。
  • matchタグ
match
type: tdlogを指定してください。
apikey: YBIWirteOnlyAPIKeyを指定してください。
buffer_type: バッファリング方法を指定します。
buffer_path: バッファリングのパスを指定します。
endpoint: YBIのエンドポイントを指定します。https://ybi.jp-east.idcfcloud.comを指定してください。
flush_interval: データの送信間隔を指定します。ここでは10秒間隔で指定しています。
use_ssl: SSL通信の有無を指定します。

さてこれでnginxのログをtd-agent経由でYBIにアップロードする準備が整いました。

Step11: YBIへのデータアップロード

Step11-1: アクセスログのアクセス権限設定

このままだとtd-agentnginxのアクセスログへのアクセス権限がないので以下のコマンドで読み込みできるようにします。

chmod
# ls -ld /var/log/nginx/
drwxr-x--- 2 www-data adm 4096 Nov 13 09:19 /var/log/nginx/
# chmod +x /var/log/nginx/
# ls -ld /var/log/nginx/
drwxr-x--x 2 www-data adm 4096 Nov 13 09:19 /var/log/nginx/
#

Step11-2: td-agentの再起動

以下のコマンドでtd-agentを再起動して、設定を反映させます。

td-agent_restart
# /etc/init.d/td-agent restart
 * Restarting td-agent td-agent                                          [ OK ] 
#

Step11-3: nginxの起動

以下のコマンドでnginxを再起動します。

nginx_restart
# service nginx restart
 * Restarting nginx nginx                                                [ OK ] 
#

Step11-4: Webサーバにアクセス

このままではアクセスログは出力されませんので、curlコマンドでnginxにアクセスします。
念のため5回アクセスしておきます。

curl
# curl http://localhost
# curl http://localhost
# curl http://localhost
# curl http://localhost
# curl http://localhost
# sleep 10 # 10秒間待機

さてこれでデータアップロードが完了したはずです!

Step12: YBIでの集計処理

とりあえずYBIにデータがアップロードされているかを確認します。

Step12-1: 全件検索  

以下のコマンドを実行してデータが格納されていることを確認します。
以下コマンドオプションの意味となります。

  • query: YBIにクエリを投げるサブコマンドとなります。
  • -w: このコマンドの終了するまでプロンプトを戻さないオプションとなります。
  • -t presto: クエリタイプを指定しておりここではprestoを指定しています。
  • -d ybi_handson_20141128: "ybi_handson_20141128"というDBに対するクエリであることを表しています。
  • "SELECT * FROM www_access": www_accessというテーブルに対する全件検索のクエリを表しています。
select_all
# td query -w -t presto -d ybi_handson_20141128 "SELECT * FROM www_access"
Job 149489 is queued.
...                                                                                 +------+------+--------+---------+------+--------+-------------+------+------+------------+
| host | path | method | referer | code | remote | agent       | user | size | time       |
+------+------+--------+---------+------+--------+-------------+------+------+------------+
| -    | /    | GET    | -       | 200  | ::1    | curl/7.35.0 | -    | 612  | 1415853825 |
| -    | /    | GET    | -       | 200  | ::1    | curl/7.35.0 | -    | 612  | 1415853828 |
| -    | /    | GET    | -       | 200  | ::1    | curl/7.35.0 | -    | 612  | 1415853829 |
| -    | /    | GET    | -       | 200  | ::1    | curl/7.35.0 | -    | 612  | 1415853830 |
| -    | /    | GET    | -       | 200  | ::1    | curl/7.35.0 | -    | 612  | 1415853831 |
+------+------+--------+---------+------+--------+-------------+------+------+------------+
5 rows in set
#

上記のように5件のデータが登録されていることがわかると思います。
スキーマ定義なしにtd-agentとYBIでいい感じに構造体情報に変換してデータを格納しているのがわかるかと思います。

Step12-2: ブラウザアクセスデータ取得

localhostからのアクセスだけでは面白くないのでブラウザでアクセスしてみます。

再度お使いのWebブラウザでnetwork1のIPアドレスにアクセスしてみてください。
以下のような画面が表示されるはずです。

welcome_nginx.png

もう一度以下のコマンドを実行して全件検索してみます。

select_all
# td query -w -t presto -d ybi_handson_20141128 "SELECT * FROM www_access"
Job 149500 is queued.
+------+------+--------+---------+------+----------------+--------------------------------------------------------------------------------------------------------------------------+------+------+------------+
| host | path | method | referer | code | remote         | agent                                                                                                                    | user | size | time       |
+------+------+--------+---------+------+----------------+--------------------------------------------------------------------------------------------------------------------------+------+------+------------+
| -    | /    | GET    | -       | 200  | ::1            | curl/7.35.0                                                                                                              | -    | 612  | 1415853825 |
| -    | /    | GET    | -       | 200  | ::1            | curl/7.35.0                                                                                                              | -    | 612  | 1415853828 |
| -    | /    | GET    | -       | 200  | ::1            | curl/7.35.0                                                                                                              | -    | 612  | 1415853829 |
| -    | /    | GET    | -       | 200  | ::1            | curl/7.35.0                                                                                                              | -    | 612  | 1415853830 |
| -    | /    | GET    | -       | 200  | ::1            | curl/7.35.0                                                                                                              | -    | 612  | 1415853831 |
| -    | /    | GET    | -       | 200  | xxx.xxx.xxx.xxx | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 | -    | 396  | 1415854425 |
+------+------+--------+---------+------+----------------+--------------------------------------------------------------------------------------------------------------------------+------+------+------------+
6 rows in set
# 

新たにGlobalIPアドレスのデータが追加されていることがわかりますね。
これでどのような端末、クライアントツールでアクセスが行われているかということを簡単にSQLで調べることができますね。

おわりに

結構簡単にWebサーバのログをSQLライクなインターフェースで解析ができる環境を構築できたと思いますが、いかがでしたでしょうか。
YBIにはこの他にも強力なデータインポートツールであるSDKもありますので是非お試しください!

おわりにおわりに・・・
今後の弊社のハンズオンの満足度向上のためお手数なのですがアンケートにご協力ください。

おしまい。

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