Elasticsearchでソースコードを検索 Code App

# はじめに

最近追加されたKibanaのCode Appでは、GithubやGitlabなどのリポジトリを読み込んで、Language Serverを使ってソースコードを解析、コードや変更履歴、解析結果もインデックスに溜め込んでくれます。
これ使うと、簡易コードビューワーになります。
＃簡易っていうわりに、重いんですけどね・・・

今のところ、対応しているLanguage ServerはJavascript(typescript)とJavaのみっぽいです。Language Serverの管理画面にはGoも出てくるんですが、読み込むプラグインが表示されないので、多分使えないんでしょう。

## 準備

特にありません。
が、プロキシを挟まない環境が必要です（最近のKibana Appはプロキシに対応してないやつが、ちょいちょいありますよね。Mapsもそうだし・・・）。

## Code Appの起動

起動すると、以下のような画面が表示されます。
まだ、リポジトリを読み込ませて無いので、なんもありません。

![Screenshot_2019-05-20 Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/56732898-f17d-72ae-a18e-427f5c69f33e.png)

## リポジトリの読み込み

試しに、[nodegit](https://github.com/nodegit/nodegit.git)を読み込ませてみます。

![Screenshot_2019-05-20 Kibana(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/2030e02e-9d7b-13fe-29da-9e66eb2069dd.png)

しばらくすると、リポジトリのクローンとインデクシングが終わり、以下のような表示となります。

![Screenshot_2019-05-20 Kibana(3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/3f042f9e-92fd-7c75-c4b6-d3cda8cb5efc.png)

## リポジトリの表示

では、リポジトリを表示して見ます。

![Screenshot_2019-05-20 Kibana(4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/55753a0c-5cb4-171a-d3a5-aaa93f6e62ff.png)

左側にはディレクトリ構造と、コードを表示してる場合はそのコード内の構造が以下のように表示されます。

![Screenshot_2019-05-20 Kibana(9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/97fa3678-cfa4-3927-0939-9ae867377e38.png)

コードの一部にカーソルを持っていくと、その部分の詳細が表示されたりします。

![Screenshot_2019-05-20 Kibana(6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/b99552b5-34dd-da31-7bb8-18a2f02c86d0.png)

## リポジトリの検索

検索してみます。上部の検索ボックスにキーワードを入れると、リポジトリ内でひっかかったものが出てきます。

![Screenshot_2019-05-20 Kibana(7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/c053ada2-e3ed-2371-abb1-a59847cfee90.png)

適当に選ぶと、ちゃんと当該箇所にジャンプしてくれます。

![Screenshot_2019-05-20 Kibana(8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/8a6b2a5c-1b6e-ad64-5635-eb095d36b2f1.png)

## その他

他には、コードの修正がいつ行われたのかや、ヒストリなども見ることができます。

![Screenshot_2019-05-20 Kibana(10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/d08bc1ce-e1d2-439f-9e36-c529c1265e9b.png)

![Screenshot_2019-05-20 Kibana(11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/72584e14-499a-6d4d-4934-860bbc012c5a.png)

## 問題点

色々あります。

### プロキシに対応していない

内部で使っているnodegitに適切なオプションを指定すれば解決しますが、オプションで指定できると良いですね。
てか、これ対応してくれないと、企業では使えない・・・

### ローカルリポジトリに対応していない

これは、色々な要因があります。
https://host:port/path/to/repo.git
とある場合、内部で使っている [is-ssh](https://github.com/IonicaBizau/is-ssh)のせいで、プロトコルが`ssh`であると見なされてしまいます。

さらに、解析結果を格納するインデックス名として「host:port」の部分を使おうとしますが、インデックス名には「:」が使えないのでエラーになります。

さらにさらに、「host」部分がIPアドレスの場合、オプションである`hostWhiteList`のチェック方法に問題があってうまくいきません。
例えばIPアドレス部分が「10.0.1.10」だったとすると、ホスト名を「0.1.10」（第一オクテットを除いた部分）として取り出してしまい、`hostWhiteList`に「10.0.1.10」と入れているとマッチしません。
＃`hostWhiteList`に「0.1.10」を指定するのもどうかと思うので・・・

### dockerイメージを使うと落ちる

Javascript Language Serverを使った場合だけです。
いつの間にか、Kibanaのコンテナが落ちています。ログを見ると・・・

```
{"type":"log","@timestamp":"2019-05-21T14:40:34+00:00","tags":["code","ts@127.0.0.1:41273","info"],"pid":1,"message":"Launch Typescript Language Server at port 41273, pid:undefined"}
events.js:174
      throw er; // Unhandled 'error' event
      ^

Error: spawn node ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
```

なんだかわかんないけど、Language Serverを起動しようとして落ちています。
[コード](https://github.com/elastic/kibana/blob/master/x-pack/plugins/code/server/lsp/ts_launcher.ts#L51-L60)を見ると、


```javascript
       const spawnTs = () => { 
         const p = spawn( 
           'node', 
           ['--max_old_space_size=4096', installationPath, '-p', port.toString(), '-c', '1'], 
           { 
             detached: false, 
             stdio: 'pipe', 
             cwd: resolve(installationPath, '../..'), 
           } 
         ); 
```

んー・・・ `node`起動しようとしてるけど、パスが通ってない？

```patch
diff --git a/x-pack/plugins/code/server/lsp/ts_launcher.ts b/x-pack/plugins/code/server/lsp/ts_launcher.ts
index e8195ce..605621e 100644
--- a/x-pack/plugins/code/server/lsp/ts_launcher.ts
+++ b/x-pack/plugins/code/server/lsp/ts_launcher.ts
@@ -50,7 +50,7 @@ export class TypescriptServerLauncher implements ILanguageServerLauncher {
      } else {
        const spawnTs = () => {
          const p = spawn(
-          'node',
+          resolve('node/bin/node', './'),
            ['--max_old_space_size=4096', installationPath, '-p', port.toString(), '-c', '1'],
            {
              detached: false,

```

な感じにパッチ当ててdockerイメージ作り直したら動いた！

# おわりに

まぁ、まだまだベータなので良いですが、せめてプロキシぐらいは対応してほしい・・・