ぼくは明日、昨日のじぶんに頼りたい

明日のためのメモです。

VSCodeで未保存ファイルが見当たらなくなった時

主にVSCodeを利用しています。
便利機能で同じWindowを開いた場合に、未保存のファイル(一度も保存してない)も含めてファイルを開いてくれています。
書き捨てのSQLだったり、保存する必要ないかなというものを書いています。
しかし、書き捨てなんですがたまに同じようなことしようと思ったときに、未保存なので見当たらなくなりました。

未保存ファイルの保存ディレクト

Windowsの場合は以下のディレクトリに未保存ファイルがありました。
%AppData%\Code\Backups

teratail.com

なぜ見当たらなくなった

「Hot Exit」という機能で未保存ファイルのバックアップを維持してくれています。
結果的に未保存ファイルは見つかったので、「Hot Exit」は機能していました。
ディレクトリ単位でWindowを開いたので、どのディレクトリ開いたときに未保存ファイル作成したのか分からなくなったということでした。1週間前のことだとしても
これは別の対策が必要なのかもしれません。

  • Files
    • off
    • onExit (default)
      • 2つのWindowにそれぞれ未保存ファイルがある場合は、保存しろダイアログが表示される
      • 1つのWindowに未保存ファイルがある場合は、保存しろダイアログが表示されない
    • onExitAndWindowClose
      • 2つのWindowにそれぞれ未保存ファイルがある場合でも、保存しろダイアログが表示されない

onExitのデフォルトの挙動が未保存ファイルを乱雑させないし、いい感じの設定なんだと個人的に理解しました。

Chromeのアクセス履歴を可視化してみる

1年間に自宅PCやスマートフォンで検索、閲覧した履歴を分析できたら自分が今年興味あったことなど振り返れるかなと思いました。可視化というレベルのことはできてません。
(ちなみに仕事は完全に会社の端末でアカウント等も別のものを利用しているので対象外となります)

Googleから取得した自分のデータ

Google データ エクスポート」で以下をエクスポート

  • Chrome」を選択

    • Bookmarks(HTML)
    • BrowserHistory(JSON)
      • 見た感じ1年分(2020/12/30があったので)はエクスポートされました。(今回は1年分あればOKなので、深堀してません)
    • ReadingList(HTML)
  • 「マイ アクティビティ」

    • 検索(HTML)
      • JSONを指定して2回ほどエクスポートしてみたのですが、なぜかHTMLで出力されてしまった

利用するデータとしては、結果的に上記で取得した「BrowserHistory」(JSON) と「%LOCALAPPDATA%\Google\Chrome\User Data\Default\Bookmarks」(JSON) を用いることになりました。

そして私の技術力のおかげで、単純なSQLで集計することになりました。

集計準備

JSONデータをPostgreSQL(14.1)に突っ込んで単純なSQLで集計します。

以下の集計データを保存するテーブルを適当に用意しました。

-- BrowserHistory
CREATE TABLE browser_histories (
  browser_history_id SERIAL NOT NULL,
  favicon_url text,
  page_transition text,
  title text,
  url text NOT NULL,
  host text NOT NULL,
  path text,
  query text,
  hash text,
  client_id text,
  time_usec bigint NOT NULL,
  access_datetime timestamp NOT NULL,
  PRIMARY KEY (browser_history_id)
);

以下を参考にjqで整えて登録することにしました。
dev.to

$ docker exec -it postgres14 sh

# jqインストール
$ apt -y update
$ apt -y install jq

# jsonデータを取り込みやすいように変換
$ cat /var/tmp/BrowserHistory.json | jq -cr '."Browser History"[]' | sed 's/\\[tn]//g' | sed 's/\\"/\\\\"/g' > /var/tmp/BrowserHistory_output.json

# 以下はじかれた
# "title":""#...
# # Color red='\0...
# 単純にシングルクォートを置換しようとするとほかのシングルクォートのところがダメになり、
# めんどくさくなり、タイトルにpathみたいなの書かれていたgithubのアクセスのタイトルを手動で削除した
# https://github.com/a01361/a01361.github.io

# データ仮置きテーブル作成
$ psql -h localhost -p 5432 postgres -U postgres -c "CREATE TABLE tmp_browser_history_json (data jsonb);"

# インポート
$ cat /var/tmp/BrowserHistory_output.json | psql -h localhost -p 5432 postgres -U postgres -c "COPY tmp_browser_history_json (data) FROM STDIN;"
-- 仮置きテーブルから登録:browser_histories
INSERT INTO browser_histories
  (favicon_url, page_transition, title, url, host, path, query, hash, client_id, time_usec, access_datetime) 
SELECT
  data->>'favicon_url' AS favicon_url,
  data->>'page_transition' AS page_transition,
  data->>'title' AS title,
  data->>'url' AS url,
  -- host
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '/.*','') AS host,
  -- with path
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '\?.*', '') AS path,
  -- with query
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '\#.*', '') AS query,
  -- with hash
  REGEXP_REPLACE(data->>'url', 'https?://','') AS hash,
  data->>'client_id' AS client_id,
  CAST(data->>'time_usec' AS bigint) AS time_usec,
  TO_TIMESTAMP(CAST(data->>'time_usec' AS bigint) / 1000000) AS access_datetime
FROM tmp_browser_history_json;

sedをぱっと使えるようになりたいです。来年の課題とします。
集計して気づきましたが、「with path」のとこでhash(#)が含まれるようになってしまっていました。来年の課題とします。

集計結果

対象期間は、2021/1/1 00:00:00から2021/12/29 23:59:59までとしました。

年間にアクセスしたChrome経由でWebアクセスした件数:77,323件
年間にアクセスしたユニークなホスト数:4,605件
年間にアクセスしたユニークなパス数(クエリーパラメータを除いたもの):22,602件
年間にアクセスしたユニークなパス数(クエリーパラメータを含めたもの):30,681件

年間にアクセスしたホストのトップ15

# ホスト 件数
1 www.google.com 8714
2 mail.google.com 4228
3 github.com 2859
4 connpass.com 2667
5 ap-northeast-1.console.aws.amazon.com 2654
6 chrome: 2647
7 qiita.com 2632
8 news.yahoo.co.jp 2615
9 www.amazon.co.jp 2318
10 www.udemy.com 1817
11 console.aws.amazon.com 1727
12 www.youtube.com 1328
13 us-west-2.console.aws.amazon.com 1040
14 trello.com 1038
15 blog.hatena.ne.jp 1022

Google検索のアクセスが全体の11%と予想通りで、次点のGmailが予想より見てしまっているという感想です。
あとは3%台でGitHubAWSコンソールやQiitaとエンジニアっぽいサイトにアクセスしてるみたいです。
connpassは今年も緊急事態宣言下があり、いろいろ参加してみたいと思いやってみたので色々探した結果上位に位置したのだと思います。ただ、スマホアプリでアクセスしているTwitterやYahooはここに現れてきていないことに注意したいと思います。
「Speaker Deck」でクエリーパラメータ含まない時に同一パスでのアクセスが多くて、よく参照しているものがあったのかと思いましたが、「?slide=3」とスライドごとにクエリーパラメータで表示されていたオチでした。

Gmailの閲覧が多かった対策でもないですが、不要なメールマガジンの配信は停止しました。(毎年恒例ではあります)

ブックマークの整理

ブックマークを整理するために以下のテーブルを適当に用意しました。
インポートするデータはGoogleからエクスポートしたものではなく、「%LOCALAPPDATA%\Google\Chrome\User Data\Default\Bookmarks」のJSONデータです。

-- Bookmarks
CREATE TABLE bookmarks (
  bookmark_id SERIAL NOT NULL,
  date_added_msec bigint NOT NULL,
  date_added_datetime timestamp NOT NULL,
  guid text NOT NULL,
  id text NOT NULL,
  name text,
  type text,
  url text,
  host text,
  path text,
  query text,
  hash text,
  PRIMARY KEY (bookmark_id)
);

先ほどと同じくjqで整えて登録しました。

$ docker exec -it postgres14 sh

# jsonデータを取り込みやすいように変換
$ cat /var/tmp/Bookmarks | jq -cr "recurse | select(.children?) | .children[]" | sed 's/\\[tn]//g' | sed 's/\\"/\\\\"/g' > /var/tmp/Bookmarks.json

# データ仮置きテーブル作成
$ psql -h localhost -p 5432 postgres -U postgres -c "CREATE TABLE tmp_bookmark_json (data jsonb);"

# インポート
$ cat /var/tmp/Bookmarks.json | psql -h localhost -p 5432 postgres -U postgres -c "COPY tmp_bookmark_json (data) FROM STDIN;"

jqで上手くいかないところがあり以下に助けてもらいました。
namonakimichi.hatenablog.com
jqをぱっと使えるようになりたいです。来年の課題とします。

-- 仮置きテーブルから登録:bookmarks
INSERT INTO bookmarks
  (guid, id, name, type, url, host, path, query, hash, date_added_msec, date_added_datetime) 
SELECT
  data->>'guid' AS guid,
  data->>'id' AS id,
  data->>'name' AS name,
  data->>'type' AS type,
  data->>'url' AS url,
  -- host
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '/.*','') AS host,
  -- with path
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '\?.*', '') AS path,
  -- with query
  REGEXP_REPLACE(REGEXP_REPLACE(data->>'url', 'https?://',''), '\#.*', '') AS query,
  -- with hash
  REGEXP_REPLACE(data->>'url', 'https?://','') AS hash,
  CAST(data->>'date_added' AS bigint) AS date_added_msec,
  -- https://stackoverflow.com/questions/51343828/how-to-parse-chrome-bookmarks-date-added-value-to-a-date
  TO_TIMESTAMP((-11644473600000 + CAST(data->>'date_added' AS bigint) / 1000) / 1000) AS date_added_datetime
FROM tmp_bookmark_json;

トラップではないですが起算日(date_added)のところは以下に助けてもらいました。
stackoverflow.com

雑にアクセス履歴とのぶつけて件数を確認します。ブックマークからのアクセスという意味ではなく、ブックマークに登録されているURLにアクセスしているかを調べています。

-- ブックマーク登録しているURLの利用状況
SELECT
  bookmarks.bookmark_id,
  bookmarks.date_added_datetime,
  bookmarks.name,
  groupby_path.path,
  groupby_path.count AS p_count,
  groupby_path.last_access_datetime AS p_last_access_datetime,
  groupby_query.query,
  groupby_query.count AS q_count,
  groupby_query.last_access_datetime AS p_last_access_datetime,
  groupby_hash.hash,
  groupby_hash.count AS h_count,
  groupby_hash.last_access_datetime AS p_last_access_datetime
FROM bookmarks
LEFT JOIN LATERAL (
  SELECT
    browser_histories.path,
    COUNT(*) AS count,
    MAX(browser_histories.access_datetime) AS last_access_datetime
  FROM browser_histories
  WHERE browser_histories.path = bookmarks.path
  GROUP BY browser_histories.path
) AS groupby_path
  ON TRUE
LEFT JOIN LATERAL (
  SELECT
    browser_histories.query,
    COUNT(*) AS count,
    MAX(browser_histories.access_datetime) AS last_access_datetime
  FROM browser_histories
  WHERE browser_histories.query = bookmarks.query
  GROUP BY browser_histories.query
) AS groupby_query
  ON TRUE
LEFT JOIN LATERAL (
  SELECT
    browser_histories.hash,
    COUNT(*) AS count,
    MAX(browser_histories.access_datetime) AS last_access_datetime
  FROM browser_histories
  WHERE browser_histories.hash = bookmarks.hash
  GROUP BY browser_histories.hash
) AS groupby_hash
  ON TRUE
ORDER BY
groupby_path.count DESC NULLS LAST, 
groupby_query.count DESC NULLS LAST, 
groupby_hash.count DESC NULLS LAST

登録されていたブックマークの件数:1,739件
今年1年でブックマークに登録しているURLでアクセスしていない件数:1,568件

なんとなくわかってはいましたが9割いらない可能性があるブックマークでした。
必要なら検索して見つけられる可能性があるので、機械的に削除しまってもいいのですが。
ただ、ブックマークした日で並べてその当時どのようなことに興味を持っていたのかは確認してから削除したいなと思いました。おそらく一生消せないやつかもしれません。
何も片付いてない。

VSCode Neovimを使ってみたかった

VSCode Neovimを使ってみようと思ったのでメモします。

marketplace.visualstudio.com

私はWindows10を使っています。
後から気づきましたがWSLに入れるのもありみたいです。(Use WSLが設定にあった)

拡張機能のInstallationに書かれてることやっていく

Install the vscode-neovim extension.

この拡張をインストールします。

Install Neovim 0.5.0 or greater.

ライトユーザなのでUse Ctrlはチェックを外しておく、これで今まで通りCtrl+aとかは使える状態になります。

クライアント証明書認証のメモ

クライアント証明書関連のメモです。

証明書を変換

knowledge.digicert.com

上の記事を参考に変換しようと思いましたが、拡張子がp12とpfxとかよくわからないレベルと気づきました。 以下の記事を読んで、p12とpfxは同じものと理解する(ことにした)

# 証明書(クライアント証明書)ファイルをエクスポートする
% openssl pkcs12 -password pass:<パスワード> -in <PKCS#12ファイル名>.p12 -clcerts -nokeys -out <証明書ファイル名>.pem

SSLを理解するための基礎ネゴシエーション

上の資料の「ネゴシエーションの手順」で、ホント意味わかってない人に流れを説明してくれています。
ありがとうございます。

  1. Client Hello
  2. Server hello
  3. Server Certificate *
  4. Server Key Exchange *
  5. Certificate Request *
  6. Server Hello Done
  7. Client Certificate *
    • クライアント証明書をサーバに送る
  8. Client Key Exchange
  9. Certificate Verify *
  10. Change Cip
  11. Finished
  12. Change Cipher Spec
  13. FInished

yumでUnicodeDecodeError

直接、証明書とは関係なのですが、パッケージ管理ツール(yum)を使えない環境でtcpdumprpmでローカルインストールしようとしてエラー(UnicodeDecodeError)発生して焦りました。

memo-off.blogspot.com

% LANG=C yum localinstall *.rpm

解析したいことできて環境への影響ありませんでした。 パケットキャプチャのやり方は以下を参考にしました。

www.imrcry.jp

使いたいバージョンのpsqlをCloud9環境に入れる

ただAWS Cloud9とかで起動したインスタンスpsqlを使いたかったです。

$ type psql
bash: type: psql: not found
$ type mysql
mysql is /usr/bin/mysql

準備

検索してみるとyumで入れたりするのはあったのですが、好きなバージョンを入れたいのでメモします。

とりあえず、File Browserでほしいバージョンを決めます。

www.postgresql.org

OSはAmazon Linux 2を使っています。

$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

インストール

私は12系を使いたかったので以下の手順になりました。

$ wget https://ftp.postgresql.org/pub/source/v12.9/postgresql-12.9.tar.gz
$ tar xvzf postgresql-12.9.tar.gz
$ cd postgresql-12.9
$ ./configure --prefix=/home/ec2-user/environment/postgresql-12.9/
$ make
$ sudo make install

$ /home/ec2-user/environment/postgresql-12.9/bin/psql --version
psql (PostgreSQL) 12.9
$ alias psql12='/home/ec2-user/environment/postgresql-12.9/bin/psql'
$ psql12 --version
psql (PostgreSQL) 12.9

結果的にmakeに時間かかるのでおとなしくyumでいいのではと思ってしまいました。
作業用のAMIを作るのがいいのですかね。

RedashをAWS上に構築

世間から何周も遅れて構築してみたいと思ったので試してみました。
可能な限り無料となるように、AWS初心者が悪戦苦闘したメモです。 (個人利用です)

考えられた構築方法

公式の方法を活用して構築したいと思います。
Setting up a Redash Instance

  • Redash公式AMIで構築
    • 不採用
  • Redash公式Dockerイメージを用いてコンテナ管理マネージドサービス上で構築
    • 不採用
  • Redash公式Dockerイメージを用いてEC2で構築
    • 採用

Redash公式AMIで構築

結果的に不採用です。 Redash公式にAWS EC2 AMIを使って構築する方法がありました。
先人たちのブログ等を拝見すると無料枠のインスタンスでは確実に動作しなそう(スペック的に)。さらに学習にもならないと思ったので却下しました。

Redash公式Dockerイメージを用いてコンテナ管理マネージドサービス上で構築

Redash公式にDockerがあるではないかと思い、EKSは厳しいけどECSはハンズオン(Fargate)もやったことがあったので軽い気持ち(なんかモダンだしって理由)で手を出しました。EC2起動タイプは無料枠だと。

VPCなどは適当に設定済み。 RedisはElastiCache、PostgreSQLはRDS(この時はなんかおかしいなと思いつつECSに夢中)。
ECS側でポチポチしていたら、EC2インスタンスできるのかなって勝手に思ってしまっていたがそんなことはなく、ドキュメントを読もう。
Amazon ECSLinuxコンテナインスタンスの起動-AmazonElastic Container Service
Amazon ECS-Optimized Amazon Linux 2 AMI」を使うとECSにインスタンス認識されたので1つ解決。AMIはdeprecatedなんでした。
セットアップ周りが終わったので節約のためにNATゲートウェイを削除したら、なんか動かなくなり。
一応プライベートサブネットに配置していたので。EC2インスタンスはインターネットに出られないとだめっぽい(ドキュメントのどこかに書いていたのような)
そして、EC2インスタンスが無料枠の対象ではないのです。残念ですが却下しました。

そもそもFargateは現状で無料枠はないのですが、たぶん今の私ではデバッグできないと思うので結果的に諦めることになったと思います。
RedashをECS上で構築して, Cloudformationでコード管理する - Qiita いったん諦める参考になりました。
AWS Fargateを本番運用した所感 - コネヒト開発者ブログ

Redash公式Dockerイメージを用いてEC2で構築

初心者が初心に戻り作業再開です。

Dockerとdocker-composeをインストール

# ※ コマンドは抜粋です
sudo yum -y update
sudo amazon-linux-extras install -y docker
docker version

wget https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)
sudo mv docker-compose-$(uname -s)-$(uname -m) /usr/local/bin/docker-compose
sudo chmod -v +x /usr/local/bin/docker-compose
docker-compose -v

amazon-linux-extras install -y dockersudo yum install dockerは結果的に同じらしい

ここでRDSが無料枠の対象になっていないことに気づきました。db.t3.microを使っていたというか一番低いので選択できるのこれだった。
getredash/setup: Setup scripts for Redash Cloud Imagesのdocker-compose.ymlを使うことにしたのでPostgreSQLもとりあえずコンテナで動かすことにしました。動作しているのを早く見たい気持ちです。

# ※ コマンドは抜粋です
sudo docker-compose run --rm server create_db
sudo docker-compose up -d

docker ps打てず、なんかもっさりしてる、DBも含めてコンテナ起動したら1GBだと足りなそう、今って結局AMIで丸っと動かしてるのと同じだよねと気づきました。
とりあえず再起動したい。EC2はどうやって再起動する作法なのか、vSphereのリセットの感覚でマネコンから「インスタンスを再起動」を押下する。何も起こらなかった(っぽい)。

とりあえず、Dockerのサービスが起動しないようにして、えいやで以下のコマンドを実行しました。

sudo systemctl disable docker
sudo shutdown -r now

再起動後、再度接続すると通常運転。
やっぱりdocker-composeで油断して起動したのが原因とわかる。
Dockerサービス起動してないからdocker psとかstopとかできないことがわかる。
Start the docker daemon without starting containers that set to restart automatically - Stack Overflow
なるほど、RestartPolicyはそこを見てるんだ。もっさりしているので、サービスは停止してalwaysをnoに書き換える

ls -la /var/lib/docker/containers/

# そんな感じか、、

vi hostconfig.json
"RestartPolicy":{"Name":"always","MaximumRetryCount":0}"RestartPolicy":{"Name":"no","MaximumRetryCount":0}

あらためてコンテナ起動しなおして状況を確認。一人しか生き残れてない過酷な状況でした。

docker ps -a
CONTAINER ID   IMAGE                         COMMAND                  CREATED             STATUS                        PORTS                                       NAMES
3b3a010a4b43   redash/redash:10.0.0.b50363   "/app/bin/docker-ent…"   About an hour ago   Exited (0) 15 minutes ago     5000/tcp                                    redash-adhoc_worker-1
a1e2d686b1d9   redash/redash:10.0.0.b50363   "/app/bin/docker-ent…"   About an hour ago   Exited (0) 15 minutes ago     5000/tcp                                    redash-scheduled_worker-1
a8bb0a103a2c   redash/redash:10.0.0.b50363   "/app/bin/docker-ent…"   About an hour ago   Up 7 minutes                  0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   redash-server-1
bd9ca8192f79   redash/redash:10.0.0.b50363   "/app/bin/docker-ent…"   About an hour ago   Exited (137) 15 minutes ago   5000/tcp                                    redash-scheduler-1
4ec3459875b0   postgres:11.13-alpine         "docker-entrypoint.s…"   About an hour ago   Exited (0) 29 minutes ago                                                 redash-postgres-1

とりあえず、DBは外に逃がしたい。
でも、RDSでPostgreSQLにしたら無料枠の対象のt2.micro選べなくて料金こんくらいかかりますって出たんですよ。
RDSでどうにかしたい。デフォルトで選択されてる13系ではなく12系にすると無料枠にできました。

でも、さっき1人しか生き残れてなかったような、
RestartPolicyを戻して再度コンテナを起動。

docker ps
fatal error: runtime: out of memory

そうだSwapを足そう。
スワップファイルを使用して Amazon EC2 インスタンスのスワップ領域としてメモリを割り当てる
はい。物理メモリの半分で行きましょう。

sudo dd if=/dev/zero of=/swapfile bs=128M count=4
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon -s

起動するようになりました。
とりあえず、疎通確認。

# EC2 → RDSを確認  
curl -v telnet://{DB インスタンス識別子}.{アカウントの特定の地域の固定識別子}.ap-northeast-1.rds.amazonaws.com:5432

# EC2 → ElastiCacheを確認  
curl -v telnet://{ノード名}.{?}.0001.apne1.cache.amazonaws.com:6379

フルオープンではなく、ちゃんと接続できている。ブラウザからもRedash開けました。

ちなみに環境変数は以下を参考に
qiita.com

PYTHONUNBUFFERED=1
REDASH_ALLOW_SCRIPTS_IN_USER_INPUT=true
REDASH_COOKIE_SECRET=
REDASH_SECRET_KEY=
POSTGRES_PASSWORD=
RDS_ENDPOINT=
REDASH_DATABASE_URL=
ELASTIC_CACHE_ENDPOINT=
REDASH_REDIS_URL=redis=//${ELASTIC_CACHE_ENDPOINT}/0
REDASH_DATE_FORMAT=YYYY/MM/DD
REDASH_LOG_LEVEL=INFO
REDASH_SENTRY_DSN=
SENTRY_TRACES_SAMPLE_RATE=1.0

VSCodeのマークダウン編集環境を整理

VSCodeを利用しています。
拡張機能やショートカットキーを活用して個人的に気持ちよくマークダウンを書けるような環境を整理したいと思います。

インストールした拡張機能

参考サイトには他にも拡張機能が紹介されていましたが、結果的に以下の拡張を使っていくことにしました。

Markdown All in One

Markdown All in One - Visual Studio Marketplace
色々と便利にしてくれているみたいです。
以下のショートカットキーを使います。

機能 ショートカットキー
~~ で囲う (取り消し線) Alt + s
`で囲う (インラインコード span) Ctrl + q
```で囲う (コードブロック block) Ctrl + Alt + q
選択した各行をリスト化(-)する (繰り返し押下することで+ や1. に切り替える) Ctrl + Alt + l

※ 下の3つは以下のようにコマンドにキーバインドを割り当ててます。

{
  "key": "ctrl+alt+q",
  "command": "markdown.extension.editing.toggleCodeBlock",
  "when": "editorTextFocus && editorLangId == 'markdown'"
},
{
  "key": "ctrl+q",
  "command": "markdown.extension.editing.toggleCodeSpan",
  "when": "editorTextFocus && editorLangId == 'markdown'"
},
{
  "key": "ctrl+alt+l",
  "command": "markdown.extension.editing.toggleList",
  "when": "editorTextFocus && editorLangId == 'markdown'"
}

Markdown Checkbox

Markdown Checkbox - Visual Studio Marketplace
チェックボックスを便利にしてくれます。
以下のショートカットキーを使います。

機能 ショートカットキー
リスト付きでチェックボックスを生成 Ctl + Shift + c
チェックボックスのチェック状態を切り替え Ctrl + Shift + Enter

Markdown Preview Github Styling

Markdown Preview Github Styling - Visual Studio Marketplace
GitHub風にプレビュー表示してくれるようになります。
個人的にサイドに開きたいのでデフォルトのショートカットキーを変更してます。
以下のショートカットキーを使います。

機能 ショートカットキー
サイドにプレビューを開く Ctl + k
{
  "key": "ctrl+k",
  "command": "markdown.showPreviewToSide",
  "when": "!notebookEditorFocused && editorLangId == 'markdown'"
}

参考