java.util.loggingの出力の扱いをどうするか
java.util.loggingのログが出力されてStackdriver上でERRORログ扱いになってしまう(結果、ERRORレベルのログの中で重要度の高いログが埋もれてしまう)ことに対処したいと思っている。 今回のケースだと下記のライブラリが該当する。
GitHub - GoogleCloudPlatform/cloud-sql-jdbc-socket-factory
接続するだけで、
INFO: Connecting to Cloud SQL instance [xxxxxx:asia-northeast1:xxxxx] on IP [35.190.xxx.xx].
というようなログをERRORレベルで吐いてしまう。
LogManager.getLogManager.reset()
とすれば出なくなる。しかし全く出ないのもまずので、試行錯誤している。
下記のように実装してみた。
val globalLogger = Logger.getLogger("com.google.cloud.sql.mysql.SocketFactory") globalLogger.setUseParentHandlers(false) globalLogger.getHandlers.foreach(h => { globalLogger.removeHandler(h) h.close() }) globalLogger.addHandler(new StreamHandler(System.out, new CustomFormatter))
これを入れればでなくなるが、これを実行するタイミングが難しい。
CustomFormatterは下記のように実装している。
class CustomFormatter extends Formatter { override def format(record: LogRecord): String = s"""{ | "severity": "${record.getLevel}", | "messsage": "(${record.getLoggerName}) ${formatMessage(record)}" |} |""".stripMargin.replace("\n", "") + CoreConstants.LINE_SEPARATOR }
試行錯誤続く。
次はこのあたりを試してみる。
ExecutionContextを自分で作る場合
とりあえず雑に
val es: ExecutorService = Executors.newFixedThreadPool(1000) implicit val executionContext: ExecutionContext = ExecutionContext.fromExecutorService(es)
とやってみたが、どれだけスレッド数使うのか計測しないと分からない。
val es: ExecutorService = Executors.newCachedThreadPool() implicit val executionContext: ExecutionContext = ExecutionContext.fromExecutorService(es)
とりあえずこれでスレッドをどう使ってるか見てみる。
"Class JavaLaunchHelper is implemented in both..."の警告メッセージは1.8.0_152で修正された
MacのIntellijでJavaを実行すると出てきてた警告メッセージ。
objc[8427]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_141.jdk/Contents/Home/bin/java (0x109de34c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_141.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10a7264e0). One of the two will be used. Which one is undefined.
問題ないメッセージなのだけど、赤い字をなるべく出したくないのでできれば消したかった。 バグらしく、これまで副作用なくこのメッセージを出さなくする方法がわからなかったのだけど、Java1.8.0_152のバージョンでこのバグが修正された。
めでたく出なくなってスッキリ。
「網羅的テストが可能な擬似コード」?
読んでもよくわからない。ただ、いまの自分の課題感に近い話題だということは分かる。テストコードを書いても、テストできている部分がごく一部である実感だから、テストを書いても安心できない。
後でもう一度読むとともに、関連することを調べてみる。
Djangoでシンプルなヘルスチェックをつける
ロードバランサの疎通をさせるために、ヘルスチェックのURLパスを作ってそこで200を返す必要があるとき。
すごくシンプルな方法があった。
- urls.py
urlpatterns = [ url(r"^", lambda r: HttpResponse()), (略) ]
ビューはコールバック関数。
これで/
へのアクセスに対して200を返してくれる。
cloud_sql_proxyのsidecar containerを立てる
GCPのCloud SQLへのつなぎ方にはいくつか方法があるが、Kubernetes内にあるpodから接続するにはアプリのコンテナと同一pod内にcloud_sql_proxyのコンテナを立ててつなぐ方法で設定した。
基本的にはここにあるテンプレートどおりやっていけば問題ないが、GCP上で実行する前提だと、いくつかの設定は不要。
containers: (アプリのコンテナの設定) - name: cloudsql-proxy image: gcr.io/cloudsql-docker/gce-proxy:1.09 imagePullPolicy: Always ports: - containerPort: 3306 command: - /cloud_sql_proxy - -dir=/cloudsql - -instances=foo:asia-northeast1:bar=tcp:0.0.0.0:3306 volumeMounts: - mountPath: /cloudsql name: cloudsql volumes: - name: cloudsql emptyDir:
これでいける。インスタンスを設定する部分の foo:asia-northeast1:bar
の部分は、
gcloud sql instances describe [インスタンスID]
で取得できる。 あとはアプリ側からは、127.0.0.1:3306向けに接続するだけでOK。
getClass.getCanonicalNameはNullになることもある
@ trait FooFilter { val filterName: String } defined trait FooFilter @ val a = new FooFilter{ override val filterName = this.getClass.getCanonicalName } a: AnyRef with FooFilter = ammonite.$sess.cmd1$$anon$1@3d904e9c @ a.filterName res2: String = null
よく考えると当たり前だけど、traitをnewしたものに対してはnullになっちゃう。
@ class BarFilter extends FooFilter { override val filterName = this.getClass.getCanonicalName } defined class BarFilter @ new BarFilter().filterName res4: String = "ammonite.$sess.cmd3.BarFilter"
これならもちろん値ある。