HttpLoggingInterceptorのJsonログを整形して表示する

ふと思いついて調べてみたらさくっとできて便利だと思ったので📝です。

HttpLoggingInterceptor

OkHttpには、HttpLoggingInterceptorという便利なInterceptorが用意されています。 このクラスを利用することで、API通信時のヘッダー、レスポンスやリクエストボディーなどを簡単にLogcat上で確認できます。

基本的にな使い方や、どのような設定ができるか等は、以下のREADMEを読むのが良いと思います。

github.com

このクラスを利用することで、レスポンスやリクエストボディーなどの値を確認できますが、デフォルトの設定ではLogcatに表示されるJsonや配列の値は整形されません。 ここでは、表示する内容を事前に整形してログに表示するようにする方法をメモ程度に紹介です。

ログデータを整形する

HttpLoggingInterceptorには、コンストラクタ経由でLoggerを渡すことができます。 デフォルトでは、単純にlogを表示するだけの処理を行う、事前にライブラリ側が用意するLoggerがセットされています。

// HttpLoggingInterceptor.kt
class HttpLoggingInterceptor @JvmOverloads constructor(
  private val logger: Logger = Logger.DEFAULT
) : Interceptor {
...

interface Logger {
    fun log(message: String)

    companion object {
      /** A [Logger] defaults output appropriate for the current platform. */
      @JvmField
      val DEFAULT: Logger = object : Logger {
        override fun log(message: String) {
          Platform.get().log(message) // 単純にlogを表示するだけの処理を行っています
        }
      }
    }
  }
...

整形するためには

カスタムなHttpLoggingInterceptor.Loggerを定義し、HttpLoggingInterceptorのコンストラクタに渡すことで、どのような値をログに表示するかを制御できます。

以下、GsonとMoshiを用いた実装例です。

Gson

internal object InterceptorLogger : HttpLoggingInterceptor.Logger {
  private val gson = GsonBuilder().setPrettyPrinting().create()

  override fun log(message: String) {
    if (message.isJsonOrArray()) {
      Platform.get().log(gson.toJson(JsonParser.parseString(message)))
    } else {
      Platform.get().log(message)
    }
  }
}

private fun String.isJsonOrArray() = startsWith('{') || startsWith('[')

Gsonの場合は、setPrettyPrinting()という設定をして初期化することで、整形したJsonの値を返してくれます。

Moshi

// Moshi
internal class InterceptorLogger(moshi: Moshi) : HttpLoggingInterceptor.Logger {
  private val adapter = moshi.adapter(Any::class.java).indent("   ")

  override fun log(message: String) {
    if (message.isJsonOrArray()) {
      val jsonValue = JsonReader.of(Buffer().writeUtf8(message)).readJsonValue()
      Platform.get().log(adapter.toJson(jsonValue))
    } else {
      Platform.get().log(message)
    }
  }
}

private fun String.isJsonOrArray() = startsWith('{') || startsWith('[')

Moshiの場合は、adapterに対してindentというのを設定できます。各階層ごとにindentをうまく挿入して整形してくれます。

参考リンク等

Kotlin error関数

この記事内のKotlinのコードは、kotlin-stdlib-common 1.3.72 で確認しています。


見つけて便利だと思ったので📝です。

Javaでは、Non-nullが想定される値がnullだった際、例外を投げるコードを以下のように書けます。

if (nonNullIsExpceted == null) {
  throw new IllegalStateException("nonNullIsExpceted should not be null.");
}

上記のようなコードをKotlinでは以下のように書くことができます。

パターン1: throwを使う

if (nonNullIsExpceted == null) {
  throw IllegalStateException("nonNullIsExpceted should not be null.")
}

val valid = nonNullIsExpected ?: throw IllegalStateException("nonNullIsExpceted should not be null.")

パターン2: error関数を使う

if (nonNullIsExpceted == null) {
  error("nonNullIsExpceted should not be null.")
}

val valid = nonNullIsExpected ?: error("nonNullIsExpceted should not be null.")

Kotlinの例は、パターン1も2も同じ意味のコードとなります。 error関数の実装はこのようになっています。 渡したメッセージとともにIllegalStateExceptionを初期化しthrowしているのみです。

/**
 * Throws an [IllegalStateException] with the given [message].
 *
 * @sample samples.misc.Preconditions.failWithError
 */
@kotlin.internal.InlineOnly
public inline fun error(message: Any): Nothing = throw IllegalStateException(message.toString())

短かく書けて直感的だと思いました。 また、message引数がNon-nullで、必ず何かしらのエラーメッセージを記述するAPI仕様になっているのも良いなと思いました、まる。

kotlinlang.org

2020年6月を振り返る

梅雨、、かな? 引き続きリモートしています。

6月を振り返る

本読んだり

blog.shoheikawano.com

↑の本だったり、その他基礎教養的な本とかを読み始めました、、Youtube最近見ているのですが、みんな一般教養すごいあるなと危機感を覚えて買ってみているというかんじです。週末ちびちび読んでます。

競馬

競馬の賭けに何回かチャレンジした。だいたい毎回数千円くらい。 負けまくっている。楽しいけど難しいけどあれは結局運ですね。

ふるさと納税

今年分選んだりしてた。 包丁とか、しゃぶしゃぶとか。 楽しみだ。

その他

CA.apk

7月は久しぶりに登壇予定です。初リモート登壇なのでドキワクちょい不安。 cyberagent.connpass.com

Upload観始めた

シーズン2早く始まらないかなー

www.youtube.com

ストーリー・オブ・マイ・ライフ観てきた

「アカデミー賞受賞」みたいな言葉に弱いんですよね。観てきました。 回想シーンと現在のシーンが行き来することが多くてちょっとだけ追いつくのに大変でした。 きれいな感じの映画でした。

www.youtube.com

旅行とかとくになく家にいるばっかりであれだなーとは思いつつ、競馬とか新しいことはちょっとずつやってみているみたいなかんじです。

あ、あとはSwitchでTETRIS 99と、ぷよぷよも最近はやりはじめてます。ぷよぷよは奥が深すぎてまだまだ。

書く内容ないのは引き続き。

以上です。6月もお疲れさまでした!

「不機嫌な職場」を読んだ

「不機嫌な職場」を読んだ

ふと古本屋で見つけて買って読んでみたって感じです。

2008年に書かれているので、もう10年以上前の本です。買ってから知ったのですが、弊社のことも書かれていて驚きました。 以下はちびちび読んでようやく読み終えた後、再度ぱらぱらめくりながら読み直してメモ程度に書いたものです。

今の働き方とその要因

  • 今(少なくとも、本執筆当時)の日本の働き方
    • 職場で関わらない
    • 協力しあわない
    • 生産性/創造性低下している
    • 自分を守ろうとする心理、など

上記の要因の一つとして、構造的要因(=タコツボ化)が挙げられるという感じです。 タコツボ化したというのは、一人ひとりの仕事が明確されて役割が分担され、個人の力はあげられるような仕組みとなったが、逆に連携する力やつながりが勝手にひろがっていくような仕組みではなくなった、ということです。

以前と今の職場の比較

以前の職場 - 周りの人たちと関わる仕組みがたくさんあった - 社員の職務領域があえて緩く設定されていた(仕事の定義があえて曖昧だった) - インフォーマルネットワーク、評判情報流通などが強くワークしていた

最近の職場 - 成果至上主義 - ジェネラリスト<専門的知識の深さを評価する - 個々人のつながりよりも、効率化を重視した動きが増えた

今の組織に対してすぐ行えること

  • 今起きていることを客観的に分析する
    • 組織内にある感情を考察する
  • 個々人の問題ではなく組織の問題であることを把握・共有する

そのほか

  • 組織力=個人の力×個人間のつながり
  • 築城三年落城一日
    • 組織作りや個々人の信頼関係は築くのに時間かかるけど崩れるのは一瞬
  • 目的のない移動は無駄かもしれないが、考えられた異動では新たな人間関係を作る

刺さった文章とか

共通の目標や、価値観の共有化についての重要性に関する章にて

短期的な行政追求に追われ、この大切な資源を組織全体に行き渡らせる努力を、近年忘れてこなかっただろうか。

人は多様である。いいところを認めてもらって嬉しくないはずがない、自分がなにか貢献できないか、という前向きな感情を持つ。

重要なのは、自分が協力する意図と自分に協力してもらうニーズを、周りのみんなにわかってもらうための方策をみんなで実践すること。

まとめ

無限に改善できそうなトピックだと思いました。いろんな考え方があるなーと思いつつ、たしかに、と納得できる部分が多かったです。

2020年5月を振り返る

もうすぐ梅雨ですね。引き続きリモートしています。少なくとも6月いっぱいはリモートかなと思っています。

5月を振り返る

バジル

f:id:shaunkawano:20200515002630p:plain

先月はネギを育て始めたけど調子に乗ってルッコラとバジルが追加された。ルッコラには虫がわんさかついてしまって断念。自分はたまに水やりするだけ。バジルもうまく育てれるかわからないけど、バジルは本当に美味しい匂いがする。

散歩

f:id:shaunkawano:20200515002634p:plain

ちょこちょこ就業前に散歩をしているけど気分が変わっていいなと思っている。ちゃんと起きれないとできないけど。これは代々木公園。

テトリス

今更感ありますがNintendo Switchを心優しい後輩さんがすでに持っているけど抽選あったということで譲ってくれました(ありがとう、ありがとう🙏) リングフィットアドベンチャー気になっているんですがまだ購入できていないのでとりあえず無料で遊べるものを、ということでテトリスやっています。

www.nintendo.co.jp

99人同時対戦するというやつです。面白い。一回だけまぐれで一位になってから面白くてやってます。

技術

リーダーの役割に関しては、チーム内での反省点とかは無限に尽きないんですけど、今月はどっぷり新しい技術をやれた月でした。DFMまわりについてちょっとだけ詳しくなれたのでどこかで発信せねばと思っています。

内容うっっっっっっっすいけどまあいっかとひらきなおっています。

以上です。5月もお疲れさまでした!

2020年4月を振り返る

進んでいくー

4月を振り返る

3月後半同様、自粛もあり家にいるように意識した月。

特にここ行った!とかはない。最近印象深かったのを並べます。

University of the Peopleはじめた

4月から、CS基礎の授業のみを試しに受けてみている。 土日にまとめたやったり、始業前にやったりしてる。 CSの授業はPythonの本当に基礎という感じ。 Python触ったこと無かったこともあり、自分には本当にちょうどいい感じ。 英語とCSの本当に初歩のほうを両方いい感じにゆるくやっているイメージ。

掲示板形式でのディスカッションだったりコード書く宿題の提出内容を生徒同士で採点し合う仕組みがあったり、ただ課題を説いていくだけって感じではまったくない。英語を書く量は必然的に増えるのでいいなと思うのと、モチベーションが維持される?感じもあっていい仕組みだなと思う。レベルが上ったりするとかなり大変になりそうかも。

  • (翻訳を介してでも)普段から英語を読むのを定期的にやっている
  • Writingもやらないとなーって思っている人
  • 土日とか、定期的にまとまった時間がとれる人

がもしいたら特訓の方法の一つとしてはありかもしれない。(お金はちょっとは払うので、ちゃんとPayしなきゃって意識も芽生えるので。) あんまり仕組みはちゃんと調べてなくて学位は取ろうと思えばとれるってかんじくらいにしかわかってないけど以下にいろいろ情報はまとまってそうです。(もしやってる人とか興味ある人いたら連絡くれると嬉しいです)

www.englishpedia.jp

my.uopeople.edu

デカフェコーヒー豆買った

f:id:shaunkawano:20200510185120p:plain

Amazonで買ってみたデカフェコーヒー☕豆。Amazon's Choiceだった。 まえまで買っていた☕屋さんが営業休止となったので。 前飲んでいたものよりもすっぱめ。

ネギ育てはじめた

f:id:shaunkawano:20200510184956p:plain

食べたネギの根っこを、水につけて陽のあたる窓際に置いているだけなんですけど、これが結構育つ。(入れ物はペットボトルの底の部分を切り取ったもの)

↓数日〜1週間くらいでこれくらい育った印象(盛ってるかも・・) f:id:shaunkawano:20200510185749p:plain

育ちきったのはチョキチョキして味噌汁に入れたりしておいしくいただいてます。自分もネギみたいにぐんぐん成長したい。

以上です。4月もお疲れさまでした!

2020年3月を振り返る

今年も1/4くらい終了したらしい。((((;゚Д゚))))

3月を振り返る

後半の方はあんまり外に出なかったので、基本3月前半ー中ばまでのものです。

すごく変わった居酒屋に行った

居酒屋というかなんというか。

とりあえずこんなところでした。

コロナが落ち着いたら、またいつか行きたいなあ。 f:id:shaunkawano:20200331221814g:plain

ご飯は気持ち足りなかった。のでこの後餃子食べに行った

井の頭公園行った

久しぶりに行った!

そしたら春って感じだった。

戸越銀座行った

ウマウマだった。写真ないけど、焼き小龍包×🍻が最高だった。

そのほか

映画

アニメもっかい見直さなきゃって感じでした。

最近は弊社でもリモートワークが始まり、家で過ごす時間がめっきり増えました。 皆様も体調管理等には気をつけてください!

今月もお疲れさまでした!!