OmniAICreator/Qiita-1.07M huggingface dataset:
FreeBSD-STABLEをJenkins使って追いかける(Git対応)

#FreeBSDのソースがGitへ移行

先日、FreeBSD開発ソースの管理システムがsubversionからgitへ変更になりました。
これを機にJenkinsを使って、毎晩勝手にソースを更新してビルドしておき、いつでも最新にアップデートできるようにしたいと思いたち、これを書いています。

## FreeBSDのソースコードリポジトリの確認
詳しい情報は以下からたどっていき、
https://wiki.freebsd.org/git
こちらの方に記載されています。
https://github.com/bsdimp/freebsd-git-docs/blob/main/URLs.md

一通り目は通しておきましょう。
この記事はstable/12ブランチを使いますが、CURRENTやstable/11を参照する場合は上記のURLを参照してください。

## Jenkinsの準備
Jenkinsをインストールします。
pkgがお手軽です。
<pre>
\# pkg install jenkins
</pre>
jenkins自体は本題ではないので、細かいところは省略します。
きっと他にいい記事があると思います(他力本願)。
あと、Gitが使えるようにプラグインを入れておきます。

##ジョブを作成する

新規ジョブ作成でフリースタイルのジョブを作成して、以下のように設定します。
リポジトリURL: https://git.freebsd.org/src.git
ブランチ: stable/12
また、ワークスペース直下にソースがあるとこの後面倒なので、Checkout to a sub-directoryを追加してサブディレクトリにソースをチェックアウトします。ここではsrcを指定してます。

![jenkins-freebsd-git-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/9285c0c6-5510-d970-d30e-44e74a62d58a.png)

さらにビルドのスクリプトとして以下を指定します。

![jenkins-freebsd-git-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/8ca3563f-f912-d09f-4b2f-15c361c91dee.png)

```sh
export MAKEOBJDIRPREFIX=${WORKSPACE}/obj
HW_NCPU=$(sysctl -n hw.ncpu)
cd ${WORKSPACE}/src
make -j ${HW_NCPU} clean
make -j ${HW_NCPU} buildworld
make -j ${HW_NCPU} buildkernel
```

CPUコアをフルに使って並列ビルドしたいので、-jオプションでCPUの数を渡します。
ここではsysctlコマンドを使っています。使っているマシンは4コア8スレッドのタイプなので、ここでは8になりますが、sysctlを使うことで、環境に合わせて自動的に並列数が指定できます。

環境変数MAKEOBJDIRPREXでワークスペースの下にビルドしたオブジェクトの出力先ディレクトリを指定します。

MAKEOBJDIRPREXはmakeのオプションとして指定することもできるのですが、それでやるとビルド途中でエラーになることがあるため、環境変数で指定しました。

## ビルド

通常通りJenkinsでビルドを実行します。
時間をおいて何度か実行すると以下のように変更点が見えて便利。

![jenkins-freebsd-git-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/f2c60bcb-b20a-6c55-4d90-0f28337df312.png)

うまくビルドできたら1日1回など適度な間隔で定期実行しましょう。
これでいつでも最新を追えますね。

---
初めて記事書いてみたけどこれでいいのかな...？

---
PostgreSQL で現在のコネクション数をリアルタイムに確認する

負荷試験を実施しているときなど、PostgreSQL に対するコネクション数の増減をリアルタイムに監視したいことがあります。そんなとき、`psql` で実行できる以下のクエリ・メタコマンドが便利です：

```sql
SELECT numbackends FROM pg_stat_database; \watch <間隔(秒)>

-- 1秒ごとに監視したい場合
SELECT numbackends FROM pg_stat_database; \watch 1

-- 0.5秒ごとに監視したい場合
SELECT numbackends FROM pg_stat_database; \watch 0.5
```

## PostgreSQL で現在のコネクション数を確認する

現在のコネクション数は `SELECT numbackends FROM pg_stat_database;` で取得できます。`pg_stat_database` は**標準統計情報ビュー**と呼ばれるものの1つで、PostgreSQL の統計情報コレクタが収集した情報を取得できます。

## クエリの実行結果をリアルタイムに確認する

`\watch` は psql 9.3 から追加されたメタコマンドです。直前に入力したクエリを指定した間隔（秒）で繰り返して実行します。間隔を指定しない場合は2秒間隔がデフォルト値となります。[^1]

[^1]: `watch` コマンドとデフォルト秒数含めて挙動を合わせくれる配慮がにくいですね。

## 参考リンク

* [27.2. 統計情報コレクタ](https://www.postgresql.jp/document/9.2/html/monitoring-stats.html#PG-STAT-DATABASE-VIEW)
* [よく使うpsqlの便利技10選](https://masahikosawada.github.io/2018/03/16/%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86psql%E3%81%AE%E4%BE%BF%E5%88%A9%E6%8A%8010%E9%81%B8/)
* [psql PostgreSQL Client Applications](https://www.postgresql.org/docs/current/app-psql.html)
RubyでJSの即時関数みたいなことをやる

ちょっと例が悪いですが、自分用メモ。

↓こんなのがRubyで書きたかった。

```js
const filepath = (() => {
  return "hoge/moge/huga";
})();
```

別に普通に定義しても良いですが、処理部がごちゃごちゃしてくる場合は、変数の定義も処理部と切り離したいと思い、考えてみました。

```rb
class Hoge
  def initialize
    @root = root
  end

  def filepath(path)
    File.join(@root.call, path)
  end

  private

  def root
    # pathへの代入は初期化の@rootへ代入された時のみ
    path = "hoge/moge/huga"
    -> { path }
  end
end
 
hoge = Hoge.new

p hoge.filepath("a") # => "hoge/moge/huga/a"
p hoge.filepath("i") # => "hoge/moge/huga/i"
p hoge.filepath("u") # => "hoge/moge/huga/u"
p hoge.filepath("e") # => "hoge/moge/huga/e"
p hoge.filepath("o") # => "hoge/moge/huga/o"
```

この例の`root`メソッドで定義している`path`は直書きですが、なにかの処理結果を`path`に格納して使いまわしたい場合は、何度も処理を走らせる必要がないので、いい感じ。
Mac(M1)TensorFlow導入(自分でpythonを入れてしまった人におすすめ)

この記事自体は、
１ヶ月程前に書き上げました
そこから、この後Keras、Pillowで躓きそれを回避したので
その記事のURL載せておきます
https://qiita.com/inosuke-hashibira/items/b660d895d45455689143

#概要
とある記事を参考にTensorflow導入開始
しかし、AnacondaやPython公式からpythonをインストールすると
かなり躓くことがわかったので実際に回避したやり方を残す

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
回避方法に移る前にぶつかったエラーとしては
pip3 list で確認するとTensorFlow-macos は存在するが
import tensorflowをすると No module となる　
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ちなみに以下が「とある記事」になる
https://qiita.com/tomoyaeibu/items/46f2f3384a370df71d5e
特に個別でインストールしていなければ、上の記事だけでTensorFlow導入可能です



#環境
M1 MacBook Pro

#エラーの原因(推測)
そもそも,エラーの原因がプロンプトで

```
which python3 
```

とした時に出力が

```
/usr/bin/python3
```
とならないこと。
ちなみに不具合時の出力は

```
/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
```

だった。使用してるpythonが違う？(素人に詳細はわからん...)

じゃあ、/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
これを消せばいいか？ってなった

以下、やったこと(2パターン)

#その1 ファイルをコマンドや手探りで削除する
以下、記事参照
https://code-graffiti.com/how-to-uninstall-official-python3-on-mac/

bash_profileの部分はやらなくていいです
(bash_profile1が見つからなかった)

#その2 Mac初期化(その1がだめだった時の最終手段)
以下、記事参照
https://www.sin-space.com/entry/m1mac-recovery

参照記事内で実際にやったことを以下に記す(参照記事と見比べながら見るとわかる)
1.再起動
2.R + Command +電源ボタンを押しながら起動を待つ(M1でもこれでやった)
3.左上の復旧アシスタントからMacを消去を選択
4.従って、消去実行
5.「ターミナルからmacos復元する」のストレージの初期化が完了したら...という文章から従ってやった
6.あとは従って進めていくだけです

全て完了したら、一番上に載せた記事を参考にTensorFlowを導入して下さい

もっと楽な方法ないかな...
Windows Server 2019を普段使い用にセットアップ

# 経緯
Azure for studentでWindows Server 2019のライセンスが無料で入手できたので、同じく個人用途だと無料で使えるVMware Fusion Player上でセットアップします。

## 仮想マシンの設定
4コア、32GBぐらいにしておきます。
![ 2021-01-18 at 15.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301047/7318a444-d6fc-56db-6092-ff57bbd99181.png)
VRAM4GB、Retina表示にしておきます。
![ 2021-01-18 at 15.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301047/63ddff17-7e32-67e4-0f0a-e625e5815bb6.png)

### サーバーマネージャーの自動起動をオフにする
サーバーマネージャーの自動起動が邪魔なのでOFFにします。
![ 2021-01-18 at 15.12.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301047/2552297f-781f-3871-422e-76dca01d2277.png)

### ログイン時のCtrl Alt Delを無効
![ 2021-01-18 at 17.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301047/8a4aee31-c968-8572-2142-f0df7d20f988.png)


### Terminusのインストール

https://github.com/Eugeny/terminus

Windows TerminalはServer2019では使えないのでTerminusを使います。

## Node.jsのインストール
Electronアプリの開発を考えるとNode.jsはネイティブにインストールした方が良さそうです。

## MSYS2のインストール
WSLより好きです。

```sh
$ pacman -Syuu
$ pacman -S base-devel
$ pacman -S mingw-w64-x86_64-toolchain
$ pacman -S openssh vim zsh tmux git
```

### ホームディレクトリの変更

```\msys64\etc\fstab
# For a description of the file format, see the Users Guide
# http://cygwin.com/cygwin-ug-net/using.html#mount-table

# DO NOT REMOVE NEXT LINE. It remove cygdrive prefix from path
none / cygdrive binary,posix=0,noacl,user 0 0
C:/Users/minorin /home/minorin #追記
```

### 最低限の.zshrc

```.zshrc
export PATH="/bin:/usr/bin:/usr/include:/usr/lib:/mingw64/bin:/mingw64/include:/mingw64/lib:/c/Program Files (x86)/nodejs:$PATH"
```

パスを通さなきゃね。

## とりあえず完成
![ 2021-01-18 at 22.13.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301047/5fcd0e2a-a727-faa7-95d9-cad73b1409d1.png)
新しいPCでgit pushする方法[Windows10]

もともと使用していたPCと違うPC（新しいPC）で開発をしようと思い、調べたところ、結構簡単に設定が出来ました。ただ答えにたどり着くまでに、Git初心者の私はかなり時間を要したので、今後のためにも備忘録としてまとめておきます。


## ①公開鍵をGitBash上で生成
開発したいディレクトリ状でGitBashを開き、
下記のコマンドを打って、GitBash上で公開鍵を生成します。

```Bash
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/[filename]
```
~　の部分は現在のディレクトリを入力してください。
`filename`には自身の好きな名前でOK。
今回は、〇〇(自分の名前)_rsa_github とかにしておきました。

Enterを押すといろいろでてきます。
とりあえずEnterを3回押したら、公開鍵が生成されます。

```Bash
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/PCユーザー名/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/PCユーザー名/.ssh/任意のファイル名.
Your public key has been saved in /c/Users/PCユーザー名/.ssh/任意のファイル名.pub.
The key fingerprint is:
フィンガープリント
メールアドレス
The key's randomart image is:
+---[RSA 2048]----+
ランダムアートが表示される
+----[SHA256]-----+
```

次に、公開鍵が生成されたフォルダに移動します。
先ほどのログに出てきている「/c/Users/PCユーザー名/.ssh/任意のファイル名.pub」が、公開鍵が生成されたフォルダなので、

```Bash
$ cd /c/Users/PCユーザー名/.ssh/任意のファイル名.pub
```

とコマンドを打って、ディレクトリを移動。
ちなみに、.pubがついていない方は、公開鍵ではなく秘密鍵です。

次に、下記コマンドを打って、生成した公開鍵をコピーします。

```Bash
$ pbcopy < ~/.ssh/任意のファイル名.pub
```

これでOK！


## ②公開鍵をGitHub上で設定
1.GitHubを開き、「Settings」から「SSH and GPG keys」を開く。
2.「SSH keys」の「New SSH key」をクリックして開く。
3.Titleに名前を付けます。（なんでもOK）
　Keyには、先ほど生成した公開鍵を貼り付けます。
4.「Add SSH Key」をクリック。

鍵のアイコンが出てきたら設定完了です！



## ③開発したいディレクトリ上でGitBashを開き、git clone

```Bash
$ git clone リモートリポジトリのURL
```

問題なくgit cloneできたら、
ダウンロードされたローカルリポジトリの中へ移動します。


## ④ローカルリポジトリ上でgit remote add

```Bash
$ git remote add ユーザー名 リモートリポジトリのURL
```


これで完了です！


あとはいつもどおりgit add→git commit→git pushできるはず！！



## 参考サイト様
[【GitHub】端末がクラッシュ→別PCから開発を再開しようとしたらgit push出来なかったので対処した](https://qiita.com/terufumi1122/items/152610a1efae1cbc0a33)
[[Windows 10] Git BashでGitHubにSSH接続](https://qiita.com/coffee_g9/items/e1b9ab28cfa54f854308)
PHPとjqueryでJSONを使わないAjax通信をする

先輩エンジニアさんから教えていただいたjson形式ではないAjax通信を行います。
html/jqueryは以下の通り。

```html

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script>
            $(function() {
                $('#ajax_post').click(function () {
                    var hogeValue = $('#hoge').val();
                    var someValue = $('#some').val();
                    $.ajax({
                        url: 'ajaxTest.php',
                        type: 'post',
                        data: "hoge="+hogeValue+"&some="+someValue
                    }).done(function(data){
                        /* 通信成功時 */
                        $('#ajax_show').text(data);
                    }).fail(function(data){
                        /* 通信失敗時 */
                        alert('通信失敗！');          
                    });
                });
            });
        </script>
    </head>
    <body>
        <input type="text" id="hoge"><br>
        <input type="text" id="some"><br>
        <input type="button" id="ajax_post" value="送信">
        <p id="ajax_show"></p>
    </body>
</html>

```
json形式にするのって結構めんどくさいですよね。
いちいちjson形式にするほど大量のデータをやり取りしないときにいいと思います。
データベースとやり取りするときは結局Json形式で値は返ってきますが。
続いてphp。

```php
<?php
    
    $afterHoge = $_POST["hoge"];
    $afterSome = $_POST["some"];
    $afterWord = "";

    $afterHoge .= '形式ではない';
    $afterSome .= '通信成功！';
    $afterWord = $afterHoge . $afterSome;
    echo $afterWord;

```

これで簡単にフォームの値のやり取りを行います。

![スクリーンショット 2021-01-18 22.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690469/2c33e62a-dff5-f7bc-156f-5f72719cca39.png)

送信ボタンを押すと…

![スクリーンショット 2021-01-18 22.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690469/82d76476-a1b7-adad-8e1f-7e03c6e77ffb.png)

ちゃんとphpを通って返ってきました。
Docker imageのビルド時に、time zoneの選択で止まってしまうときの解決策

# 困ったこと
0からdockerイメージを作っていて、いろいろパッケージをインストールさせていたら 
ビルド中に`time zone`の選択肢が表示されて、進まなくなってしまいました。 
エラーではなさそうなのですが・・・。
# 事象
ターミナルに表示されているメッセージは次のとおりです。

```
Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.

  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
  2. America     5. Arctic     8. Europe    11. SystemV
  3. Antarctica  6. Asia       9. Indian    12. US
Geographic area: 
```
数字を押しても、Enterキーを押しても先に進まなくなってしまいます。
# 解決方法
gitのインストールコマンドよりも前に次に`DEBIAN_FRONTED`の設定を実行します。

```dockerfile
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
    && apt-get -y install git
```
# まとめ
dockerfileで`git`を`apt-get install` するときは
`DEBIAN_FRONTED=noninteractive` を先に設定しましょう。
Octoberで管理画面の複数の入力欄のデータを単一カラムにJSONで格納するのは設定だけでできる

OctoberではJSONでデータベースに格納するフィールドの管理画面を簡単に作成できる。

データをそれぞれ１カラムに格納するのではなく、１つのカラムにJSON文字列にまとめて格納したいとする。このとき、管理画面ではそれぞれの入力欄を表示して、データはJSONに変換してテーブルに格納するということをOctoberではロジックの記述無しでできてしまう。

（今のところドキュメントに記載はないが、Octoberの内部的な作りを考えると自然な挙動なので今後も変わることはないと思われる。）

例えば、hogesというカラムにfooとbarと言うデータを格納したい場合、モデルの `$jsonable`配列にカラム名の`hoges`を追加。（これにより、`$model->hoges`とアクセスするだけでJSONデータはすでに配列に変換されている。逆に、配列をアサインしてモデルをsaveするとJSONデータとしてテーブルに格納される。）

```php
class MyModel extends Model
{
    ...
    protected $jsonable = [
        'hoges',
    ];
    ...
}
```
そして、管理画面のフィールド設定（fields.yaml）では`hoges[foo]`のように配列のように記述することでsubmitしたときにOctober側でそのpostデータを配列として処理する。配列が`$model->hoges`に入れられることになるので、JSONデータとして格納してもらえる。

```yaml
fields:
    hoges[foo]:
        label: Foo
        span: auto
        type: text
    hoges[bar]:
        label: Bar
        span: auto
        type: text
```

Octoberのドキュメントでは、リピーターやデータテーブルなどのウィジェットからのデータをjsonableに設定したカラムに格納できるが、上記のようなOctoberの基本的な動作を理解していると、色々と応用が効かせやすい。
Octoberは非常に拡張性が高いので、このようなOctoberのコンセプトを理解していると独自のウィジェットなどを効率よく作成することができる。
zabbixのマップにトラフィック量を表示させる

zabbixのマップにトラフィック量を表示させる方法です。

今回の環境はZABBIX5.0.7を利用してます。

#Zabbixマップの設定
予め、マップには以下のようにホストの登録をしておきます。
登録方法は割愛します。

![SnapCrab_NoName_2021-1-18_21-53-15_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/4aa7a361-5463-4217-295e-e6e40d1237d5.jpeg)


#マップに表示させるトラフィック情報の確認
まず、Zabbixで収集した数多くあるトラフィックデータからどのトラフィックデータを表示させるのか確認します。
確認するポイントとしては、以下の2つです。
合わせて確認方法についても記載します。

* ホスト名
    * ZABBIX→設定→ホスト→対象ホストの「ホスト名」
* インターフェイス・データのキー名：例）net.if.in[ifInOctets.71]
    * ZABBIX→設定→ホスト→対象ホストのアイテム
    * 多数あるアイテムの中からマップに表示させたいものを探す
    * 例えば、PPインターフェイス01のUP・DOWNパケットを表示させたい場合のアイテムは以下の2つになります。
        ![SnapCrab_NoName_2021-1-18_21-23-59_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/11a9cfdb-c42f-3f67-3341-1b484d69a81d.jpeg)

        * `Interface PP[01]: Bits received`
        * `Interface PP[01]: Bits sent`
    * それぞれのアイテムに対応するキーは以下の通りです。
        * `net.if.in[ifInOctets.71]`
        * `net.if.out[ifOutOctets.71]`
   
以上、ホスト名とマップ上に表示させるデータのキー名の確認方法でした。
後ほど、これらのデータを利用しますので事前に確認しておくことをおすすめ致します。


#ホスト同士を結ぶリンクの設定方法
1. マップの変更をクリック
1. リンク接続したいホストを`Ctrl`キーで複数選択。

1. 要素の一括更新の画面が表示されます。ここでは何もしない。

1. マップ上部にある「リンク：追加」をクリック

1. リンクが設定されていることを確認します。
![SnapCrab_NoName_2021-1-18_21-55-47_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/e312abb3-7eec-8928-10a9-5e5295e4190e.jpeg)

1. 要素の一括更新画面の下に、リンクが設定されていることを確認します。
ここで言う、「開始」「終了」は複数選択したホストのホスト名となっています。
![SnapCrab_NoName_2021-1-18_20-21-50_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/047b9d60-8a0e-de33-08df-c059fc9d8af8.jpeg)

1. アクション：変更をクリック
1. 以下のようにラベル等を入力する画面が開きます。
リンクに対して設定できるものは以下の通りです。
    3. ラベル：ここに入力したテキストがリンクの線上に表示されます。
    4. タイプ：リンクの線の描写を選択します。デフォルトでは線。
    5. 色：リンクの色を設定します。ここでは緑色。
    6. 条件発生時の条件設定：ここでトリガーを選択することで障害発生時にリンクの線の描写や色を変化させることができます。
![SnapCrab_NoName_2021-1-18_20-30-9_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/e00b3772-ad06-5753-b7ad-656f2425e7e9.jpeg)
1. 次へ続く

#リンクへのトラフィックデータの反映
1. 要素の一括更新からリンクのラベルへの記入を行います。

1. 記入する構文としては以下の通りです。
    * `{ホスト名:キー名.last(0)}`
        * 例）`{RTX830:net.if.out[ifOutOctets.71].last(0)}`

1. トラフィックデータ以外にもテキストを表示させることもできます。
    * 例）`上り：{RTX830:net.if.out[ifOutOctets.71].last(0)}`

1. 適応をクリックすると以下のように表示されます。
![SnapCrab_NoName_2021-1-18_21-44-3_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/47f45755-ac27-f0c9-ca70-f50a62efdbd3.jpeg)

1. 右上の更新ボタンでマップを保存すると以下のようにトラフィックが表示されます。
![SnapCrab_NoName_2021-1-18_21-46-7_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/0215d264-abb1-1e6e-b5c5-cd9451a3b3d7.jpeg)

1. 応用すればこんな感じでトラフィックを表示できます。
ラベル↓
`PPPoE(OCN)
↑:{RTX830:net.if.out[ifOutOctets.71].last(0)}/↓:{RTX830:net.if.in[ifInOctets.71].last(0)}　`
![SnapCrab_NoName_2021-1-18_21-50-23_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212451/80b40c64-d790-df3f-89ea-48db1d18a035.jpeg)


#参考Webページ
Create Interactive Zabbix Maps | Learn with Examples (Tutorial)
https://bestmonitoringtools.com/create-zabbix-maps-with-examples/
パスワードを破るための攻撃


 - ブルートフォース攻撃
   - 概要：1人のユーザーに対して、様々な文字列を組み合わせて力任せにログイン試行を繰り返す攻撃。
 <br>
<br>

 - リバースブルートフォース攻撃
   - 概要：1つのPWを、様々なユーザーに対してログイン試行をする攻撃。例えば「1234」や、「password」「qwerty」などがある。（つまりブルートフォース攻撃の逆）
<br>
<br>
 
 - 辞書攻撃
   - 概要：辞書に出てくる言葉を順に使用してログインを試みる攻撃。
   - 対策：例えば「dog」「chair」などは使用しないことが求められる。
<br>
<br>

 - スニッフィング
   - 概要：盗聴する（キーロガーなど）でパスワードを知る攻撃の総称。
<br>
<br>

 - リプレイ攻撃
   - 概要：パスワードを送信しているIPパケットを取得し、まったく同じものを再度送信することでそのユーザーになりすます攻撃。これはパスワードが暗号化されていても使用できてしまう。
   - 対策：1セッションごとにランダムなセッショントークンを送付し、同一のものか確認する。（例えば、セッショントークンをパスワードに付加してハッシュ関数を計算する）
また、ワンタイムパスワードを発行する。
<br>
<br>

 - パスワードリスト攻撃
   - 概要：他のサイトで取得したパスワードのリストを利用し、不正ログインを行う。
   - 対策：他のサイトと同一のID/PWを使用することをやめる
<br>
<br>

 - レインボー攻撃
   - 概要：「レインボーテーブル」とは、平文とよく使われる暗号化によるハッシュ値の対応表のこと。たとえば、「みかん」のハッシュ値が「s7asd8」だとする。この場合、ハッシュ値を見ただけでは何が何やらわからなくとも、レインボーテーブルで「s7asd8」を探せば、その平文が「みかん」を意味するとわかる。
【Vue.js】基礎知識

#はじめに

現在、エンジニア転職活動中です。本日から、Vue.jsの学習を始めましたので、アウトプットとして記述していきます。

#なぜVue.js?

なぜ、Vue.jsの学習を始めたのかを記載します。

・転職活動用に作成しているポートフォリオが、HTML,CSSとBootstrapの多用により、サイトに動きがないため。
・GoogleTrendsにて比較を見た結果、Vue.jsの比率が高く、今後入社した際にも、Vue.jsを採用されているまたは今後採用する予定の企業も多いと感じたため（https://trends.google.com/trends/explore?date=today%205-y&q=vue.js,react.js,angular.js）
・これまでRuby,Ruby on Railsの学習に注力しており、フロントエンドの知識があまりなかったため

以上の理由により、Vue.jsの学習を初めていきたいと思いました。

#導入方法

Vue.jsの導入はダウンロードまたはCDNを利用する方法がありました。
今回はCDNを利用してVue.jsを読み込むことで、利用していきます。

```html:index.html
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
```

#基本機能

###テキストのバインディング

```html:index.html
<div id="app">
  <p>{{ message }}</p>
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
```
![](https://gyazo.com/d0b336be8f34ca3522ce8ad00cde263e.png)

###繰り返し

```html:index.html
<div id="app">
  <ul>
    <li v-for="item in list">{{ item }}</li>
  </ul>
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  data: {
    list: ['野球', 'サッカー', 'バスケットボール']
  }
})
```

![](https://gyazo.com/d98c47d3b7ba48b3ae7431242e993c8a.png)

###イベント発火

```html:index.html
<div id="app">
  <button v-on:click="handleClick">Click</button>
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  methods: {
    handleClick: function(event) {
      alert(event.target)
    }
  }
})
```

[![Image from Gyazo](https://i.gyazo.com/30acc4ccf403ab64b15d477f3237da55.gif)](https://gyazo.com/30acc4ccf403ab64b15d477f3237da55)

###フォーム入力の同期化

```html:index.html
<div id="app">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})
```

[![Image from Gyazo](https://i.gyazo.com/046f1931882cc37425c2c61c76ec06a4.gif)](https://gyazo.com/046f1931882cc37425c2c61c76ec06a4)

###条件分岐

```html:index.html
<div id="app">
  <p v-if="show">Hello Vue.js!</p>
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  data: {
    show: true
  }
})
```

[![Image from Gyazo](https://i.gyazo.com/7263960dc2e934a2b34c8175c6b80f81.gif)](https://gyazo.com/7263960dc2e934a2b34c8175c6b80f81)

###トランジションとアニメーション

```html:index.html
<div id="app">
  <button v-on:click="show=!show">切り替え</button>
  <transition>
    <p v-if="show">Hello Vue.js!</p>
  </transition>
</div>
```

```html:practice.js
var app = new Vue({
  el: '#app',
  data: {
    show: true
  }
})
```

```html:practice.css
.v-enter-active, .v-leave-active {
  transition: opacity 1s;
}

.v-enter, .v-leave-to {
  opacity: 0;
}
```

[![Image from Gyazo](https://i.gyazo.com/224e20e601c99c61a6a84d0a1baa5ece.gif)](https://gyazo.com/224e20e601c99c61a6a84d0a1baa5ece)

#おわりに

本日学んだ基本知識です。明日以降構成の内容などアウトプットしていきたいと思います。
【Rails】raty.jsを使った評価機能を作る

raty.jsを使って、railsアプリに星画像付きの評価機能を実装する方法です。jqueryが必要です。

![ 2021-01-18 21.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/9fb4a95b-e445-3f8a-7ef9-56f396f79280.png)


## 環境
```zsh
$ rails -v
Rails 5.2.4.4
```
## jqueryを導入
```rb:Gemfile
gem 'jquery-rails'
```
```zsh
$ bundle install
```
```app/assets/javascripts/application.js
//= require jquery
```

## jquery.raty.jsを作成
```zsh
$ touch app/assets/javascripts/jquery.raty.js
```
作成したファイルに、https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js 内の記述をコピペ。その後`application.js`でrequire(jqueryより後に書く)

```app/assets/javascripts/application.js
//= require jquery.raty.js
```

##星の画像を配置
https://github.com/wbotelhos/raty/tree/master/lib/images から`star-on.png`、`star-off.png`、`star-half.png`をダウンロードして、`app/assets/images`以下に配置。

## 評価を保存するカラムを持つデータを作成
```zsh
$ rails g migration addEvaluationToMovie evaluation:float
```
```rb:db/migrate/202101011111.rb
class AddEvaluationToMovie < ActiveRecord::Migration[5.2]
  def change
    add_column :movies, :evaluation, :float
  end
end
```
```zsh
$ rails db:migrate
```

## 評価投稿画面を作成
今回は例として、お気に入りの映画のタイトルを投稿する画面で、評価も一緒に投稿できるようにしてみます。

```erb:app/views/movies/new.html.erb
<h2>お気に入りの映画を投稿</h2>
<%= form_with(model: movie, local: true) do |form| %>
  <div>
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>
  <div id="evaluate_stars">
    <label>評価</label>
  </div>
  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>
<script>
  $('#evaluate_stars').raty({
    starOn: "<%= asset_path('star-on.png') %>",
    starOff: "<%= asset_path('star-off.png') %>",
    starHalf: "<%= asset_path('star-half.png') %>",
    scoreName: 'movie[evaluation]' //登録するモデル名とカラム名を記述
  });
</script>
```
```app/controllers/movies_controller.rb
def movie_params
  params.require(:movie).permit(:title, :evaluation) # evaluationを追加
end
```

## 投稿した評価を表示
ここでは例としてindexページに評価を表示します。

```erb:app/views/movies/index.html.erb
<h1>映画一覧</h1>
<table>
  <thead>
    <tr>
      <th>タイトル</th>
      <th>評価</th>
    </tr>
  </thead>
  <tbody>
    <% @movies.each do |movie| %>
      <tr>
        <td><%= movie.title %></td>
        <td class="movie-evaluation" data-score="<%= movie.evaluation %>"></td>
      </tr>
    <% end %>
  </tbody>
</table>
<script>
  $('.movie-evaluation').raty({
    readOnly: true,
    score: function() {
      return $(this).attr('data-score');
    },
    path: '/assets/'
  });
</script>
```

## 参考
- [jQuery Raty - A Star Rating Plugin](https://www.alpinestyle.co.il/media/vendor/jquery.raty-1.4.3/)
- [wbotelhos/raty: :star2: Raty - A Star Rating Plugin](https://github.com/wbotelhos/raty)
- [jquery.raty rails導入 - Qiita](https://qiita.com/Seungbaek_Seo/items/dcc38e8b23def28b8f1a#%E6%8A%95%E7%A8%BFreview%E3%81%AE%E5%B9%B3%E5%9D%87%E3%82%92%E8%A1%A8%E7%A4%BA)
React/TypeScript: useStateのコールバック関数をpropsで受け取る時のtypeの定義の仕方備忘録

DispatchとsetStateActionを使う。

# コード

```javascript:子コンポーネント
import React, { Dispatch, SetStateAction } from "react";

type Hoge = {
  fuga: string;
  setFuga: Dispatch<SetStateAction<string>>;
};
KeyTrigger に紐づけたコマンドが何回も発報する

## 困りごと

私のための備忘録。

以下のように KeyTrigger とコマンドを紐づけたコントロールを用意し、それを TabControl->TabItem に置いてみたところ、掲題のようにコマンドが何回も発報する現象に遭遇。  

正確に言うと、タブの選択状態が切り替わるたびに KeyTrigger とコマンドの紐づけが再生成されているようで、切り替えた回数だけコマンドが呼び出されていました。

```xml:Region
<UserControl ...略
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:p="http://prismlibrary.com/">
    <ComboBox ItemsSource="{Binding XXX, Mode=OneWay}"
              Text="{Binding YYY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              IsReadOnly="{Binding ZZZ, Mode=OneWay}"
              IsEditable="True">
        <i:Interaction.Triggers>
            <i:KeyTrigger ActiveOnFocus="True" Key="Return">
                <p:InvokeCommandAction Command="{Binding HogeCommand, Mode=OneTime}"/>
            </i:KeyTrigger>
        </i:Interaction.Triggers>
    </ComboBox>
</UserControl>
```

```xml:Window
<Window ...略
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:p="http://prismlibrary.com/">
    <Window.Resources>
        <Style x:Key="RegionContent" TargetType="{x:Type ContentControl}">
            <Setter Property="p:RegionManager.RegionManager" Value="{Binding RegionManager, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=OneWay}"/>
        </Style>
    </Window.Resources>
    <TabControl>
        <TabItem Header="タブ１">
            <ContentControl Style="{StaticResource RegionContent}" p:RegionManager.RegionName="Tab1Region"/>
        </TabItem>
        <TabItem Header="タブ２">
            <ContentControl Style="{StaticResource RegionContent}" p:RegionManager.RegionName="Tab2Region"/>
        </TabItem>
    </TabControl>
</Window>
```

## 手がかり

かなり前ですが、同じような現象で困っていた方を発見。
どうやら Blend 時代からの仕様らしく、KeyTrigger を使わずに対応する必要がありそうです。

[stack overflow: Blend KeyTrigger fires multiple times](https://stackoverflow.com/questions/5948158/blend-keytrigger-fires-multiple-times)

## 対応策

InputBindings に変えたらこの現象は収まりました。

```xml:Region
<UserControl ...略
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:p="http://prismlibrary.com/">
    <ComboBox ItemsSource="{Binding XXX, Mode=OneWay}"
              Text="{Binding YYY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              IsReadOnly="{Binding ZZZ, Mode=OneWay}"
              IsEditable="True">
        <ComboBox.InputBindings>
            <KeyBinding Command="{Binding HogeCommand, Mode=OneTime}" Key="Return"/>
        </ComboBox.InputBindings>
    </ComboBox>
</UserControl>
```
[自分用メモ]typescriptをes6にコンパイルできない

typescriptをes6にコンパイルするにはtsconfig.jsonのtarget:ES6を有効にしてVScodeのターミナルにtsc ファイル名 というコマンドを入力すれば無事ES6にコンパイルできるはずだが、今回エラーが発生したのでその対処法をメモしておく。

ターミナルにnpx tsc ファイル名　--target es6と入力すれば無事ES6にコンパイルできる。

npxがないと私の場合はコンパイルできませんでした。
WSL：リモートデスクトップ接続とssh

Windows Proで、画面を使う自動処理をさせながら、他の処理もさせたいという状況。
リモートデスクトップだと、1ユーザーしか入れないので、WSLのsshdと併用することにした。
sshdは、WSLのコンソールが走ってなくても動いてるので、やりたかったことは大体できてる。
悪くない環境。

# WSLのインストール

[Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)

[WSL2とHyper-Vの関係](https://qiita.com/matarillo/items/ca1eecf8f9a3cd76f9ce)

# マイクロソフトアカウントでリモートデスクトップ

2要素認証を使っているWindowsのアカウントに、リモートデスクトップ接続をする。

## サーバー側

- コントロールパネルからシステムを選択
- リモートアクセスの許可
    - このコンピュータへのリモート接続を許可する
    - リモートデスクトップユーザー
        - 追加していないかも。。忘れた
- 複数のセッションを許可する
    - [リモートデスクトップ 複数セッションを許可する](https://blogs.osdn.jp/2017/10/01/multi-rdp.html)
    - Windows Serverでないとダメっぽい
    - 違うアカウントで接続すればよいか？

## クライアント側

- リモートデスクトップクライアントを起動
- マイクロソフトアカウントでログオン
    - MicrosoftAccount\xxx@live.jp で接続（MicrosoftAccount\はなくてもよいかも）


# sshd on WSL

この設定でやったら、WSLのアカウントのパスワードでログオンできた。証明書でやりたいけど、プライベートネットワークに限定しているから、当面は良いか。

- [WSL Ubuntu18.04でSSHパスワード認証](http://my-web-site.iobb.net/~yuki/2018-12/soft-tool/wsl-ubuntu1804-ssh-pwauth/)

```
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
$ sudo vi /etc/ssh/sshd_config

   （2カ所修正します）

$ diff /etc/ssh/sshd_config /etc/ssh/sshd_config.org
56,57c56,57
＜ PasswordAuthentication yes
＜ PermitEmptyPasswords no
---
＞ PasswordAuthentication no
＞ #PermitEmptyPasswords no
```

- ssh permission denied
    -  windows terminalでsshに接続しようとしたら、permission Denied で接続できない。WSLのコンソールからだとログオンできる。
ん、と思ってみてみたら、TerminalのPowerShellからssh叩いてた。
エラーを調べようと authlogを探したけど見当たらない。調べてみねば。
    - 原因は、ユーザー名が 'hostname\username'として接続を行うため。
    - ssh -l username host とすることで、powershellからでも接続できる。 

        - [Windows ターミナルとは](https://docs.microsoft.com/ja-jp/windows/terminal/)
        -  [ついに完成「Windows Terminal」の機能と使い方まとめ](https://www.atmarkit.co.jp/ait/articles/2005/28/news018.html)


### WSLに外部から接続できない問題

WSLでサービスを立ち上げても、他のノードから接続できない。
この問題の対策については、以下の記事にまとめてある。

- [Yeat Another WSLに外部から接続できない問題](https://qiita.com/plus_sum/items/dfdf20a2669c55c11031)


## auth.log (rsyslog)
authl.logを記録する方法がありました。

- [Monitor SSH attempts in Windows Subsystem Linux](https://unix.stackexchange.com/questions/518997/monitor-ssh-attempts-in-windows-subsystem-linux)

（高橋訳）
何らかの理由で、WSL上ではrsyslogサービスがデフォルトで実行されていません - 残念ながら、私はその理由を見つけることができませんでした。
以下のようにして起動することができます: service rsyslog start
サービスを起動すると/var/log/auth.logと/var/log/syslogファイルが表示されます。
スタートアップごとに実行したい場合は、いくつかのチュートリアルを見つけました。例: https://dev.to/ironfroggy/wsl-tips-starting-linux-background-services-on-windows-login-3o98

```
% sudo service rsyslog start
```

## Windows logon時にサービスを自動起動する

まずは、パスワードなしでsudoできるコマンドを登録する
viで編集したいので、こちらを参考にvim.basicに変更

- [[Ubuntu] visudoのエディタをnanoからvimに変更する](https://qiita.com/koara-local/items/35b999631b6ab41fdc9f)

```
$ sudo update-alternatives --config editor
```
あとは、こちらの記事を参考に設定

[WSLでサービスを自動起動する（勝手翻訳：WSL Tips: Starting Linux Background Services on Windows Login）](https://qiita.com/plus_sum/items/fb39e22035d3400a81b5)

こちらは、まだ試していない
[豚吐露＠wiki Windows>tips>WSLにSSH接続したい](https://w.atwiki.jp/ohden/pages/864.html)

# ファイル共有

[ネットワーク資格情報の入力が毎回出る/アクセスできない時の対処 – Windows10](https://itojisan.xyz/trouble/19255/)

https://worktoolsmith.com/microsoft-account-remote-desktop/
SQLのEXISTSについて①

前回のANY/SOMEやALLからの流れから、今回はEXISTSについて説明しようと思います。
EXISTSには二種類の使用方法があり、「存在判定」と「相関副問い合わせ」と言われています。
今回は存在判定について説明します。

|Code|Name|
|:-----|:-----|
|01|田中|
|02|鈴木|
|03|中村|
|04|山崎|

|Code|Score|
|:-----|:-----|
|01|80|
|02|90|

まずは、上記のような二種類のテーブルを用意します。

```ruby:SQL
SELECT * FROM TABLE1 
WHERE EXISTS (
    SELECT * FROM TABLE2 
    WHERE TABLE2.Code = '02') 
    AND TABLE1.Name = '中村' ;
```

このとき、カッコの内側のSQLの抽出条件であるTABLE1.Code = '02'のレコードが存在しているので、カッコの外側のSQLも実行されます。
結果は以下の通りです。

|Code|Name|
|:-----|:-----|
|03|中村|

もうひとつ、SQLを実行してみます。
カッコの内側のSQLの抽出条件だけ変更しています。

```ruby:SQL
SELECT * FROM TABLE1 
WHERE EXISTS (
    SELECT * FROM TABLE2 
    WHERE TABLE2.Code = '03') 
    AND TABLE1.Name = '中村' ;
```

TABLE2にはCode = '03'に該当するレコードがないため、外側のSQLは実行されません。
このため、もしこのSQLを実行してもなにも抽出されません。
[React] Reactの学習をします（1-3）式の埋め込み

#Reactの学習をします（1-3）

Reactの学習をしてみることにしました。
前回の記事　：　[[React] Reactの学習をします（1-2）コンポーネントの分割](https://qiita.com/IwashiMorino/items/6289ac108c54e23438e0 "[React] Reactの学習をします（1-2）コンポーネントの分割")

##教材

[Reactチュートリアル1：犬画像ギャラリーを作ろう](https://zenn.dev/likr/articles/6be53ca64f29aa035f07#%E5%BC%8F%E3%81%AE%E5%9F%8B%E3%82%81%E8%BE%BC%E3%81%BF "Reactチュートリアル1：犬画像ギャラリーを作ろう")

likr さんが公開している「Reactチュートリアル1：犬画像ギャラリーを作ろう」という記事を教材に学習させて頂きます。

素晴らしい教材をありがとうございます。

##学習日記

本日は「式の埋め込み」～「繰り返し」までやりました！

##式の埋め込み

※ 教材から箇条書き的に抜粋させて頂きます。

>・JavaScript の式を JSX に埋め込むためには {式}のように書きます。

この {式} の使い方はとても重要ですね。

##コンポーネントと props

※ 教材から箇条書き的に抜粋させて頂きます。

>・次は親コンポーネントから子コンポーネントへプロパティを渡す方法を扱います。

>・呼び出し側の関数である親コンポーネントから、呼び出される側の関数である子コンポーネントへ props を通じてプロパティを渡すことができます。
>props は子コンポーネントの関数の引数となります。

>・JavaScript の式を渡したい場合は{}を使ってください。

>・子コンポーネントでは、関数の仮引数の props を通じて渡されたプロパティにアクセスすることができます。

##繰り返し

※ 教材から箇条書き的に抜粋させて頂きます。

>・これまでは 1 枚の画像のみを表示していましたが、Dog API から複数の画像の URL を取得してそれを一度に表示してみることを考えてみましょう。

>・URL の配列を JSX 式の配列に変換すると考えると良いでしょう。
>このような処理は配列の map メソッドでできました。

>・map メソッドで作られる JSX 式は、最も外側の要素に key 属性を付けなければいけません。

```javascript:App.js
function Gallery(props) {
  const { urls } = props;
  return (
    <div className="columns is-vcentered is-multiline">
      {urls.map((url) => {
        return (
          <div key={url} className="column is-3">
            <Image src={url} />
          </div>
        );
      })}
    </div>
  );
}
```

（Galleryコンポーネントの部分だけ抜粋させて頂きました。）

※ 下図のように表示させることができました！ありがとうございます！

![024a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897250/836a1235-c965-6215-2cbe-d54abb5175c7.png)
谷藤賢一『いきなりはじめるPHPワクワク・ドキドキの入門教室』でPHPを勉強してみた(1)

仕事のため、PHPの勉強を始めた。

タイトル通り、私が勉強に使っているのは谷藤賢一『いきなりはじめるPHPワクワク・ドキドキの入門教室』だが<strong>買ってはいけない本を買った気がする……</strong>

この本では、学習を進めるためにXAMPP(ザンプ)というサーバーをダウンロードするよう書かれているが、この記事を書いている2021年1月時点でテキスト通りにいかないことがいくつかある。

<h1>ポートのチェックの設定変更ができない</h1>
XAMPPをダウンロードしたとき、パソコンにSkypeが入っている場合、ポートを奪い合ってXAMPPが起動しない。そのために本書では「Skypeの設定で、ポートのチェックを外してください」と書いてあるのだが、<strong>現在、Skypeの設定画面からポートのチェックを外すことはできない。</strong>インターネットを検索すればなんとかポートの変更はできるが、初学者向けの本でこれはどうかと思う。

<h1>テキスト通りにやってもエラーが出る</h1>
テキストに書いてあることをただやってるだけなのに、

「Server error!
サーバ内部で障害が発生し、 リクエストに応えることができませんでした。 サーバが過負荷であるか、 CGI スクリプトにエラーがあります。
サーバーの障害と思われる場合は、ウェブ管理者までご連絡ください。
Error 500
localhost
Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/5.6.24」

というエラーが出る。

ヤフー知恵袋でも、<a href="https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12165998597?__ysp=44K144O844OQ5YaF6YOo44Gn6Zqc5a6z44GM55m655Sf44GX44CBIOODquOCr%2BOCqOOCueODiOOBq%2BW%2FnOOBiOOCi%2BOBk%2BOBqOOBjOOBp%2BOBjeOBvuOBm%2BOCkw%3D%3D">私と同じところで躓いた人がいた。</a>


「新しいテキストを買ったほうがいいんじゃないか……」と思ったが、<a href="https://royal-fummy.com/blog/php-startup-with-mamp/">【PHP】超優良入門書『いきなりはじめるPHP』をMAMPで完走するために知っておくべき５つのこと【Mac】</a>
というサイトによると、MAMPをダウンロードすれば学習を進められるらしいのでMAMPをダウンロードした。

今日はChapter3 ワクワク！プログラミング編の3-1から3-8まで進めた。


■追記
MANPをダウンロードし起動したあと、スタートを押してもstop serversにならず、接続できない場合は、Preferenes → PHPのタグを押し、「Standard Version」の初期設定がを7.3.7から、7.2.14 に変更すればいい。

HTML 4.01だからdoctype宣言が長い。

段落を<br>でなく<br/>と書いてるテキストはじめてみた。
Lombokの@Accessorsについて


@Accessors：getter/setterをカスタマイズするためのアノテーション
　　　　　　　@Getter/@Setterなどと一緒に使う
　　　　　　　オプションは "chain" "fluent" "prefix" の3種類

### 環境
Java : 1.8
Lombok : 1.18.16
(SpringBoot : 2.3.7)


## setterのメソッドチェーン化

`@Accessors(chain = true)`でsetterをメソッドチェーン化する
↓

```java
user.setName("Tom").setAge(24);
```

のように連続して記述できる

<実際に生成されるコード>

```java
public User setName(final String name) {
	this.name = name;
	return this;
}
```

<ポイント>
つけるのはクラスでもフィールドでも可、ただしどちらに付けても**クラス内に一つでも存在すると全フィールドに適用される**

## getter/setterをフィールド名で使用

`@Accessors(fluent = true)`
でgetter/setter名をフィールド名で使用できるようにする
↓

```java
String name = user.name();  // getter
user.name("Tom");           // setter
```

のようにフィールド名でgetter/setterを記述できる

<実際に生成されるコード>

```java
public String name() {
	return this.name;
}

public void name(final String name) {
	this.name = name;
	return this;
}
```

<ポイント>
つけるのはクラスでもフィールドでも可、chainと違い、フィールドに付けた場合は**そのフィールドのみに適用される**

## prefix部分を除いた名称を用いてgetter/setterを定義

```java
@Accessors(prefix = "f")
private String fName;
```

でprefix部分を除いた名称を用いてgetter/setterを定義する
↓

```java
String name = user.getName();  // getter
user.setName("Tom");           // setter
```

のようにprefix部分を除いた名称でgetter/setterを記述できる。

<実際に生成されるコード>

```java
public String getName() {
	return this.fName;
}

public void setName(final String fName) {
	this.fName = fName;
}

```

<ポイント>
つけるのはクラスでもフィールドでも可
　→クラスに付与した場合：**全フィールド**に適用、**prefixを満たさないフィールドはgetter/setterが生成されない**
　　フィールドに付与した場合：**そのフィールドのみ**に適用

<具体例>

```java
@Getter
@Setter
@Accessors(prefix = {"f", "t"})
public class User {
	private Integer id;
	private String fName;
	private Integer tAge;
}
```

↓
○実際に生成されるコード

```java
public String getName() {
	return this.fName;
}

public void setName(final String fName) {
	this.fName = fName;
}

public Integer getAge() {
	return this.tAge;
}

public void setAge(final String tAge) {
	this.tAge = tAge;
}

```
`private Integer id;`はprefixとして記述した”f”も”t”もついていないのでコードが生成されない。
「lazyload 対応」スムーズスクロールの書き方

#どうも7noteです。lazyloadを入れていてもスムーズにページ内リンクできる方法

以前表示速度が少し心配なサイトがあり、lazyload属性を使いつつもでもページ内リンクをさせたい場面がありました。

もし対策せずにどちらも入れてしまうと、画像が読み込まれていないかページ内リンクの高さ取得が上手くできず
画像が後から読み込まれることで高さが変わってしまい、本来の位置よりも上の方に移動してしまいます。

ですがjQueryのwhenを使うことでこの問題を解決することができます。

## lazyload対応スムーズスクロールの書き方



※jQueryを使用しています。jQueryってなんだという方は[こちら](URLURL)

```
$(function () {
	$('a[href^=#]').click(function(e) {
		var headerHight = 50;   /* ヘッダーの高さ(50px) */
		var href = $(this).attr("href");
		var target = $(href == "#" || href == "" ? 'html' : href);
		var position = target.offset().top - headerHight;

		$.when(
			$("html, body").animate({
				scrollTop: position
			}, 400, "swing"),
			e.preventDefault(),
		).done(function() {
			var diff = target.offset().top - headerHight;
			if (diff === position) {
			} else {
				$("html, body").animate({
					scrollTop: diff
				}, 10, "swing");
			}
		});
	});
});
```


詳しい動きの解説は参考にさせていただいたページの書き方に載っていますので省略させていただきます。

参考：https://kaiteki-chokin.com/anchor-link-lazy-loading/


## whenについて簡単に解説

whenを使うことで、**複数の非同期処理が全部終わったら、続く処理を行う**ことができます。
今回の処理ではこれを利用し、画像がlazyloadでちゃんと読み込まれた後に正しい位置までのスクロール処理を行なっています。



## まとめ

jsは様々な便利なライブラリやソースがネットにあるので1つのページに様々な種類のソースを書くことは珍しくありません。
ただ、その動き方やソースの内容や特性をしっかり理解できないと相性が悪く上手く動かない事もあります。

なので自分がソースを書くことも大事ですが、**他人のソースを読めることも大事**だと思います。

#### おそまつ
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
エラー解決を通してdeviseのメソッドuser_signed_in?とcurrent_userの理解が深まった話

# 開発環境

Mac OS Catalina 10.15.7
ruby 2.6系
rails 6.0系

# 事の発端

転職用のポートフォリオとしてオリジナルアプリを作っていたある日のことでした。
未ログインユーザーが詳細ページに遷移するリクエストをローカルで行ったところ、以下のエラーが発生

![スクリーンショット 2021-01-18 20.02.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035658/71eea597-92e5-d91e-d3f9-47ed914b0470.png)

# 解決法

結論から言うと　 user_signed_in? && 　の条件を追加することで解決しました。

エラー時のコード

```ruby:show.html.erb
<% if current_user.id == @post.user.id %>
  <div class = "btn-contents">
    <%= link_to '編集する', edit_post_path(@post.id), class: "edit-btn"%>
    <%= link_to '削除する', "#", class: "delete-btn"%>
  </div>
<% end %>
```
---
エラー解決後のコード

```ruby:show.html.erb
<% if user_signed_in? && current_user.id == @post.user.id %>
  <div class = "btn-contents">
    <%= link_to '編集する', edit_post_path(@post.id), class: "edit-btn"%>
    <%= link_to '削除する', "#", class: "delete-btn"%>
  </div>
<% end %>
```
なんとも呆気ない話でしたね。

# 原因

未ログインユーザーに対する条件を忘れたことで、current_userメソッドが未ログインユーザーのリクエストの際でも使われてしまったことが原因でした。

current_userは、現在ログインしているユーザーの情報を取得できるメソッドですが、今回の場合、ログインしていないのに、ログイン情報を取得しようとしました。

そのため、「current_user??? そもそもログインしてないんでそんな情報ないんですけど？？？」みたいな感じでrails先生に怒られてしまったと言うわけですね。

なので、まずは手前の条件で user_signed_in?メソッドを使うことで、ログインしていなければfalseが返ってくるようにします。
そうすれば、未ログイン時には後ろの条件に遷移しなくなるのでエラーが解決するわけでした。(A && B と言う記述は、Aの条件がfalseだった場合、Bの条件は参照されません）

# 対策

対策としては「メソッドに対するなんとなくの理解をやめること」だと思っています。

エラーの原因としては上記の通りですけど、根本的な原因は「メソッドをなんとなく覚えて理解したつもりで使っていたこと」だと思っています。
気をつけます、、、
[ruby]演算子について

## はじめに
こんばんは
私は某スクールに通っているものです
先月卒業したばかりなのですが学んだ事をアウトプットしております
前回、[Ruby]文字列で使えるメソッドを作ったので今回は演算子について触れたいと思います！

##演算子とは？

演算子とはプログラミングで計算したり、比較したりする時に使う記号です
これはめちゃくちゃ使うから覚えてくださいね


と言ったけどそのほとんどは小学校でやった＋とかーとかばかりだから身構えなくていいかも

|  |   |
| ---- | ----|
| ＋ |  足し算  |
|-|  引き算  |
| *|  掛け算  |
| / |  割り算  |
| %| 剰余  |
|**| べき乗|
|Math::PI |円周率（π）を合わせる定数|
|Math.sqrt|平方根を求める|


ぶちゃけ、べき乗以下は半年プログラミング学習してたけど使わんかったから頭の隅に置いておいてください

```
=> nil
irb(main):115:0> 1 + 1
=> 2
irb(main):116:0> 1 - 1
=> 0
irb(main):117:0> 1 * 2
=> 2
irb(main):118:0> 4 / 2
=> 2
```

言うまでもないけど四則演算の働き

```
irb(main):119:0> 3 / 4
=> 0
```
ちなみに小数点は表示されない
なぜならこの数字はIntegerクラスであって、Integerは数字を整数で表しているからね

```
irb(main):122:0> n = 3 / 4
=> 0
irb(main):123:0> n.class
=> Integer
```

代入されたnをclassで確認したら”Integer”と確認できました



##%(剰余）

上の図で剰余と記述されていましたが何って話ですよね？
剰余と言うのは割ったあまりを指します

```
irb(main):128:0> 9 % 7
=> 2
```

9 / 7 = 1 ・・・　余り２だから、２が表示されたわけですね

##べき乗

べき乗と言うのは簡単に言うと累乗だね

```
irb(main):131:0> 4 ** 2
=> 16
```

これを見ていただければわかりますが
4 * 4 = 16だね



## Math::PI

Math::PIは円周率
でも3.14よりより細かい計算ができるよ

```
irb(main):138:0>  3 * 3 *3.14
=> 28.26
irb(main):139:0>  3 * 3 * Math::PI
=> 28.274333882308138
```

見てわかるかもだけど小数点第二位が違う


##Math.sqrt
これは平方根を求めるメソッドだね

Math.sqrt(数字)で使えます

```
irb(main):140:0> Math.sqrt(4)
=> 2.0
```
4の場合を求めたけど√４の場合は２だね

```
irb(main):143:0> Math.sqrt(2)
=> 1.4142135623730951
```

ひとよひとよにひとみごろ、懐かしい

##最後に
演算子はこの先かなり使うから覚えよう
でもべき乗以下は頭に入れる程度でいいよ
AppleシリコンなMacをApple Configurator2で再インストールする

# AppleシリコンMacを綺麗にしたい。
 - 適当に環境構築した時に、Macをまっさらにしたいときがあると思います。
 - M1MacはIntelMacと起動の方法がちょっと違います。

# Apple Configurator 2を使って起動し直す。
 - Macを複数台持っている人は、USB-C同士でMacを接続します。
    - https://support.apple.com/ja-jp/guide/apple-configurator-2/apdd5f3c75ad/mac
- 端子の位置は上のリンクを参考にしてください。

# IntelMacの方
- 片方のMacのAppleConfigurator2を起動しておきます。

# M1Macの方
- M1Macの電源ボタンを一度おして、Macおなじみの起動音を確認します。 
- 確認後、電源ボタンと右Shiftキー、左Optionキー、左Controlキーを同時に押します。
- 上の状態で10秒数えます。数えたら、電源ボタン以外の指を話ます。電源ボタンは押し続けてください。
- 電源ボタンを押している間に、IntelMacの方のAppleConfigurator2の画面にDFUモードの画面が出てきます。
- これで完了。

# IntelMacの方
 - DFUモードの画面ので右クリックで、復元を選択します。
 - 復元を押したら、待ちます。15分くらい待ちます。M1Macのステータスバーが溜まるまで待ちます。IntelMacの画面は4/4まで行って、とまります。
 - そしたら、M1Macが起動してくるので、起動したら、ケーブルを外します。おわり。
Ajaxのローディング中にくるくる（スピナー）を表示する例


html
<button id="button" type="button">Click</button>
<div id="overlay">
  <div class="cv-spinner">
    <span class="spinner"></span>
  </div>
</div>

CSS
#button{
  display:block;
  margin:20px auto;
  padding:10px 30px;
  background-color:#eee;
  border:solid #ccc 1px;
  cursor: pointer;
}
#overlay{ 
  position: fixed;
  top: 0;
  z-index: 100;
  width: 100%;
  height:100%;
  display: none;
  background: rgba(0,0,0,0.6);
}
.cv-spinner {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;  
}
.spinner {
  width: 40px;
  height: 40px;
  border: 4px #ddd solid;
  border-top: 4px #2e93e6 solid;
  border-radius: 50%;
  animation: sp-anime 0.8s infinite linear;
}
@keyframes sp-anime {
  100% { 
    transform: rotate(360deg); 
  }
}
.is-hide{
  display:none;
}



JS
jQuery(function($){
  $(document).ajaxSend(function() {
    $("#overlay").fadeIn(300);　
  });
    
  $('#button').click(function(){
    $.ajax({
      type: 'GET',
      success: function(data){
        console.log(data);
      }
    }).done(function() {
      setTimeout(function(){
        $("#overlay").fadeOut(300);
      },500);
    });
  }); 
});



参考先：https://blog-and-destroy.com/7283
【SVN】Failed to run the WC DB work queue associated with xxxx work item 発生時の対応


# 概要
SVNクリーンアップを行った際などに下記エラーが発生した際の対処方法


```
次のパスを処理する際にクリーンアップに失敗しました。
C:\xxxx
Failed to run the WC DB work queue associated with C:\xxxx work item

yyyy
を読み書き両用に設定できません: 指定されたファイルが見つかりません。
```

# 環境
Windows10
TortoiseSVN 1.13.1

# その前に

SVNのエラーに出ている yyyy ファイルを既にどこかで開いているとこのエラーが発生することがあるため、
現在起動しているプログラムやアプリでそのファイルを開いていないか確認して下さい。

そのアプリを閉じたらクリーンアップできることがあります。
その場合は下記対応は不要です！

# 対応方法
1.
SQLite公式サイトからWindowsコマンドラインツールをダウンロードする。
https://www.sqlite.org/download.html

Precompiled Binaries for Windows
sqlite-tools-win32-x86-3340000.zip (投稿時点の最新版はこちら)

2.
ダウンロードしたファイルの中の「sqlite3.exe」を、エラーが発生する「.svnファイルがある階層」にコピーする。

3.
その階層でコマンドラインを実行して、下記コマンドを4つ入力する

``` cmd.exe
sqlite3 .svn/wc.db "select * from work_queue"
sqlite3 .svn/wc.db "select * from wc_lock"
```

この時点で何も表示されていなかったら下のコマンドはやらなくてよい。

``` cmd.exe
sqlite3 .svn/wc.db "delete from work_queue"
sqlite3 .svn/wc.db "delete from wc_lock"
```

# おまけ

リモートワークで不慣れな方に対応をするとき、ZOOMでリモート制御を行って代わりに作業すると比較的短時間で行えるかと思います。
「zoom リモート制御」
InputStreamをStringに変換したい

必要になるたびにぐぐるのに疲れたので自分用のメモとしておいておきますね(´・ω・｀)

`InputStream`をすべて読み込んで`String`に変換したい場合、おおよそ以下のように書いておけば大丈夫です。

```java
public static String readAll(InputStream in) throws IOException {
    byte[] b = new byte[1024];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int len;
    while ((len = in.read(b)) != -1) {
        out.write(b, 0, len);
    }
    return out.toString();
}
```

また`String`に変換したい`InputStream`の文字コードがUTF-8ではない場合、`ByteArrayOutputStream.toString(Charset charset)`を利用すればよいです。たとえば`InputStream`がWindows-31Jの場合は以下のように書きます。

```java
public static String readAll(InputStream in) throws IOException {
    byte[] b = new byte[1024];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int len;
    while ((len = in.read(b)) != -1) {
        out.write(b, 0, len);
    }
    return out.toString(Charset.forName("Windows-31J"));
}
```

なお車輪の再発明を避ける意味でも、Apache CommonsのIOUtilsなど、OSSのライブラリが使える場合はそちらを使いましょう(´・ω・`)

**環境情報:**

```
C:\>javac -version
javac 11.0.3
C:\>java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
```
PDFのページを結合,すぐコピペシリーズ

# PDFファイルの結合
PDFの結合をたまに使うので、すぐに使える状態で自分用に。
PyPDF2のpipインストールが必要。
以上。


```merge_pdf.py
import PyPDF2

# 別々のpdfファイルを結合します
def merge_pdf(pdf_files):
    merger = PyPDF2.PdfFileMerger()
    for pdf in pdf_files:
        merger.append(pdf)

    merger.write("merge.pdf")
    merger.close()

if __name__ == "__main__":
    pdf_files = ["a.pdf","b.pdf"]
    merge_pdf(pdf_files)    
```
[python]ライブラリramkanのインストールでエラーになる


[ramkan](https://pypi.org/project/romkan/)はローマ字/仮名変換用のライブラリ。
インストールする際にエラーが起きたので忘備録。

## エラー内容

ramkanのインストール

```
$ pip3 install romkan
```

するとこういうエラーが起きる。

```
Collecting romkan==0.2.1
  Downloading romkan-0.2.1.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /home/scaruadmin/venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-8y_m14tz/romkan_f9a5712add8043608044b16dab0fc01c/setup.py'"'"'; __file__='"'"'/tmp/pip-install-8y_m14tz/romkan_f9a5712add8043608044b16dab0fc01c/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-xw46by6f
         cwd: /tmp/pip-install-8y_m14tz/romkan_f9a5712add8043608044b16dab0fc01c/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-8y_m14tz/romkan_f9a5712add8043608044b16dab0fc01c/setup.py", line 12, in <module>
        README = open(os.path.join(here, 'README.rst')).read()
      File "/opt/rh/rh-python36/root/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 181: ordinal not in range(128)
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
```

## 解決策

pythonの言語設定が問題っぽい。

```
$ sudo vim ~/.bashrc
```

ファイルに↓を追加して保存。

```
export LC_ALL=en_US.UTF-8
```

bashの再起動

```
$source ~/.bashrc
```

おしまい

## 参考
[PythonのUnicodeDecodeErrorの対処方法 - Python入門](https://kaworu.jpn.org/python/Python%E3%81%AEUnicodeDecodeError%E3%81%AE%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95)

前提知識など
[.bash_profileと.bashrcのまとめ - Qiita](https://qiita.com/takutoki/items/021b804b9957fe65e093)
[よく使う Vim のコマンドまとめ - Qiita](https://qiita.com/hide/items/5bfe5b322872c61a6896)


## 追記
Docker使ってる場合は、bashの設定じゃなくてdockerに言語設定してもいいかもしれない。
[Docker: コンテナのlocaleを設定したい - Qiita](https://qiita.com/suin/items/856bf782d0d295352e51)
ポートフォリオサイトの制作

# はじめに
自分のスキルや成果物の可視化やGithub以外のアウトプットを一元管理するため、ポートフォリオサイトを作成しました。


今回は作成する上で気をつけたことや使用したツール、ホスティング方法について備忘録としてまとめたいと思います。

URL:  https://seiyaiwanabe.github.io/portfolio_site/

![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/e65bdd78-7c68-264b-a73f-f004b4411cc6.gif)
![ezgif.com-gif-maker (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/c0087748-f769-ee9a-3689-9bfe76087e93.gif)

# 目次
[1.記載内容](#1-記載内容)
[2.使用したサービス](#2-使用したサービス)
[3.Github Pages](#3-Github Pages)

## 1. 記載内容
ポートフォリオサイトを作成した理由は主に企業の採用担当者の方に見てもらうためです。
**「誰にポートフォリオサイトを見せたいのか」**という要素は最も大事だと思うのでここを決めることでサイト全体の構成も決まってくると思います。

今回は以下の要素を記載しました。

* **使用した言語（技術）**
* **作品紹介**
* **開発に使用したツール**
* **アウトプットへのリンク(今回はQiita)**

また工夫した点としてサイト全体に`アニメーション`を盛り込みました。
JSの練習になるのと少しでもビジュアルを魅力的にするためです。

ただし、多様しすぎるとエゴになってしまうので、線引が難しいですが、
情報を整理するという目的を忘れないことが大事だと思いました。

アプリ自体は`Ruby on Rails`で作成し、インフラにAWSを使ってデプロイしています。

## 2. 使用したサービス
コーディングはイチからしました。
`bootstrap`やテンプレートの類は使用していません。
自分の手を動かして少しでもプログラミングに慣れたかったためです。

そのため使用した外部サービスは`FontAwesome`と`Favicon作成ツール`にとどまりました。

FontAwesome（ヘッダーの中のアイコンに使用）→https://fontawesome.com/
![スクリーンショット 2021-01-18 19.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/eae19a30-0fc1-dfdc-7fd7-128a254d98c2.png)






Faviconの素材（159,700のフリーアイコンが集まるサイト）→https://icons8.jp/
![スクリーンショット 2021-01-18 19.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/f49d7a55-fc54-dbba-252c-f76b012b9104.png)
Faviconは拡張子がjpgやpngでも表示させることが出来ます。
まずダウンロードした素材のファイル名を`icon.png`に変更し`imagesディレクトリ`に格納します。
図にするとこのような階層になります。↓

![スクリーンショット 2021-01-18 20.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/745b8e3e-6925-c19a-d3c5-5f352d17e778.png)

あとはhtmlファイルに一行追記するだけです。

```php:index.html
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">　# FontAwesome導入
  <link rel="icon" type="image/x-icon" href="images/icon.png"> # 追記
  <title>Document</title>
</head>
```
これでアイコンが表示されます。

## 3. Github Pages
>GitHub Pages は、GitHub のリポジトリから HTML、CSS、および JavaScript ファイル を直接取得し、任意でビルドプロセスを通じてファイルを実行し、ウェブサイトを公開できる静的なサイトホスティングサービスです。(Github Dogs)

こちらの引用でも記載してる通り、静的なサイトのためのホスティングサービスなので動的なサイトをホスティングさせることは出来ません。なのでRailsアプリはAWSでデプロイを行っています。

今回のポートフォリオサイトのようにサーバーサイドに関与しないコンテンツを世界に公開する手段としては
Github Pagesは無料で利用できて、プロセスが簡単なのでおすすめです。

# おわりに
最後まで読んでいただきありがとうございました！
お疲れさまでした。。。
MackrelインテグレーションでGAE(Google App Engine)を監視する場合の落とし穴

メモ的共有


2020年にリリースされたMackrelのGCPインテグレーション。

GAEのみを動かしているプロジェクトの監視を入れてみた。

相変わらず、分かりやすい手順書を公開していただいているので、ポチポチと設定完！
https://mackerel.io/ja/docs/entry/integrations/gcp

しかし、待てども待てどもホスト追加されない。

ドキュメント記載の確認ポイントを調べても、解決せず。。。
https://mackerel.io/ja/docs/entry/integrations/gcp/appengine

https://support.mackerel.io/hc/ja/articles/360054013192-Google-Cloud-GCP-%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%8CMackerel%E3%81%AB%E3%83%9B%E3%82%B9%E3%83%88%E3%81%8C%E9%80%A3%E6%90%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84

ネット上にもそれっぽい悩みは見つからず。。。

そこで、GCP側を調査。

APIとサービスのダッシュボードで、インテグレーション設定したタイミングから、computeのエラーが発生していた。
手順では、GAEしか使わない環境だったので、GCE、Cloud SQLの有効化はSkipしたが、それが怪しそう。
GAEも裏ではGCE動いているし。

ということで、GCEのAPI有効化もすることで解決！
（とはいえ、反映に結構待ちます。測ってないですが体感20minほどだったかと）


ネット上にも情報見つからなかったので、あまり需要ないかもですが、他の人が同じことで困らないように残しておきます。