ioredisで謎のエラー
ioredis で謎のエラーがでてハマった。
[ioredis] Unhandled error event: ParserError: Protocol error, got "J" as reply type byte. Please report this. at handleError (/Users/jnst/go/src/github.com/Translimit/park-server/node_modules/redis-parser/lib/parser.js:190:15) at parseType (/Users/jnst/go/src/github.com/Translimit/park-server/node_modules/redis-parser/lib/parser.js:304:14)
エラーがでないコード
空のコンストラクタを使うとデフォルトで 127.0.0.1
に接続する。
import * as Redis from 'ioredis'; const redis = new Redis();
エラーがでるコード
host
と port
を指定するとエラー。
import * as Redis from 'ioredis'; const redis = new Redis(3306, '127.0.0.1');
原因
Redis の 6379 番ポートではなく、MySQL の 3306 番ポートにアクセスしてた。
このエラーだけならすぐ気づいたかもだけど、別のエラーとの複合技だったので解決に時間がかかってしまった。疲れてるようだ…。
TypeScriptとioredisのコードをJestでテストしたらコンストラクタじゃないと言われた件
TypeScript と ioredis のソースコード
TypeScript で Redis 使いたい場合は ioredis で書いてこんな感じのコードになる。
sample.ts
import * as Redis from 'ioredis'; (async () => { const redis = new Redis(); const pong = await redis.ping(); // => PONG })();
Jest のテストコード
ところが Jest でテスト書いたら実行できなくてハマってしまった。
sample.spec.ts
import * as Redis from 'ioredis'; describe('Redis', () => { it('should be return pong', async () => { const redis = new Redis(); const pong = await redis.ping(); redis.disconnect(); expect(pong).toBe('PONG'); }) });
.ts
ファイルを直接実行するので ts-jest を入れている。
$ jest TypeError: Redis is not a constructor 4 | 5 | it('should be return pong', async () => { > 6 | const redis = new Redis(); | ^ 7 | const pong = await redis.ping(); 8 | redis.disconnect(); 9 | expect(pong).toBe('PONG'); at Object.it (src/sample.spec.ts:6:19)
TypeError: Redis is not a constructor
なんでやねん
import * as Redis from 'ioredis'; const redis = new Redis();
のところでコンストラクタじゃないと言われる。書き方は正しいのに。
import Redis from 'ioredis';
に直したら動いた。間違ってるのに。
まぁそんなこともあるのかなと思ったりもしたけど、テストファイルをコンパイルして .js
ファイルにしてテスト実行してみるとエラーになる。
TypeError: ioredis_1.default is not a constructor 4 | describe('Redis', () => { 5 | it('should be return pong', async () => { > 6 | const redis = new ioredis_1.default(); | ^ 7 | const pong = await redis.ping(); 8 | redis.disconnect(); 9 | expect(pong).toBe('PONG'); at Object.it (dist/sample.spec.js:6:23)
TypeError: ioredis_1.default is not a constructor
やっぱり書き方が間違ってるいるわけだ。
原因
ts-jest
にバグがあったようだ。
"devDependencies": { "@types/ioredis": "^4.0.3", "@types/jest": "^23.3.5", "jest": "^23.6.0", "ts-jest": "^21.2.4", "typescript": "^3.1.3" }
yarn upgrade --latest ts-jest
して 23.10.4
にしたら治った。
awslogsはpython2系依存なのでgolang実装のcwをつかう
AWS の Lambda や ECS の需要が増えたことにより、CloudWatch Logs の需要も増えてると思う。
でも AWS コンソールから CloudWatch Logs はとても見にくい。そこで awslogs を使ってる人が多いと思う。
🌋 awslogs の問題点
Python2系への依存、これが非常にだるい。Python は pyenv で 3 系いれてたりするし。
$ brew info awslogs awslogs: stable 0.10 (bottled), HEAD Simple command-line tool to read AWS CloudWatch logs ==> Dependencies Required: python@2 ✔
🐾 Golang 実装の cw
$ brew info cw lucagrulla/cw/cw: stable 1.7.2 The best way to tail AWS Cloudwatch Logs from your terminal
バイナリ配布が得意な Golang 実装なので依存関係はゼロ。
📝 使い方
Homebrew からインストールできる。
$ brew tap lucagrulla/cw $ brew install cw
-p
で ~/.aws/credentials
のプロファイルを指定可能。tail -f
でリアルタイム監視できる。その後ろの第1引数で ロググループ名
、第2引数で ログストリーム名
を指定。第3引数で日時指定を UTC で指定できる。
$ cw -p <my_aws_profile> tail -f <my-log-group> <my-log-stream-prefix> <start-time>
$ cw -p jnst tail -f /ecs/my-server ecs/my-server/**** 2018-10-01T08:10:10