GCP上でHaskellプログラムからStackDriver Loggingにログを出力する
Google Cloud PlatformのVMインスタンス上でHaskellプログラムを動かし、StackDriver Loggingにログを出力する方法を調べた。
コード全体
サンプルとして、https://github.com/steshaw/google-logging-example を見つけたが、GKE(コンテナ)上で動作するものだった。
今回は、GCPのVMインスタンス上で実行ファイルを動かしたかったので、forkしてから、少しいじって、https://github.com/masatoko/google-logging-example/tree/gce-instance を作った。コード全体はこの'Main.hs'。
利用するライブラリgogol
GoogleのAPIをHaskellでいじれるライブラリgogolを使う。
https://github.com/brendanhay/gogol
https://hackage.haskell.org/package/gogol
https://hackage.haskell.org/package/gogol-logging
コードの要点
要点は、(1)MonitoredResourceDescriptorの設定、(2)ラベルの設定、(3)LogNameのフォーマットだ。
下のコードと照らし合わせながら、各要点を確認してほしい。
(1) MonitoredResourceDescriptor
https://cloud.google.com/monitoring/api/resources の表を参照して、目的のTypeとLabelを見つける。今回は、VM上のプログラムなので、Typeは'gce_instance'で、対応するラベルは、'project_id', 'instance_id', 'zone'だ。(実はこの表を参照すればいいのかは自信がないのだけれど、成功したから合っていると思う。間違っていたらご指摘ください。)
(2) ラベルの設定
任意のラベルを指定できる。コード中では、[("key", "value")]
となっているところ。
(3) LogNameのフォーマット
projects/{プロジェクトID}/logs/{任意のログID}
としないとエラーとなるので注意。
コード(解説したいところだけ)
logMsg :: Text -> Text -> IO (Rs EntriesWrite)
logMsg logId msg = do
-- ~~~~~
-- 省略
-- ~~~~~
let
entry = logEntry & leTextPayload ?~ msg
?~ Info -- Network.Google.Logging - LogEntrySeverity -- https://hackage.haskell.org/package/gogol-logging/docs/Network-Google-Logging.html#t:LogEntrySeverity
entries = [entry]
logName = "projects/" <> projectId <> "/logs/" <> logId -- (3) LogNameはこのフォーマットである必要がある!
resourceLabels = monitoredResourceLabels $ HM.fromList -- (1) https://cloud.google.com/monitoring/api/resources の'Description Labels'
[ ("project_id", projectId)
, ("instance_id", instanceId)
, ("zone", zone)
]
resource = monitoredResource -- (1) これは必須
& mrType ?~ "gce_instance" -- https://cloud.google.com/monitoring/api/resources の'Resource type Display name'
& mrLabels ?~ resourceLabels
labels = writeLogEntriesRequestLabels $ HM.fromList -- (2) これは任意
[ ("key", "value")
]
runResourceT . runGoogle env $
send
(entriesWrite
(writeLogEntriesRequest
& wlerEntries .~ entries
& wlerLogName ?~ logName
& wlerResource ?~ resource
& wlerLabels ?~ labels
)
)
実行結果
コンソール
コンソール上でプログラムを実行すると、このように出力された。(隠したいところは...
と加工しているので、出力そのままではない)
$ ./google-log logid ログメッセージ
Writing log message...
("projectId","project-id")
("description","")
("hostname","...internal")
("instanceId","53...46")
("zone","projects/64...11/zones/asia-northeast1-c")
("FromMetadata",ServiceId "default")
[Client Request] {
host = logging.googleapis.com:443
secure = True
method = POST
timeout = ResponseTimeoutMicro 70000000
redirects = 10
path = /v2/entries:write
query = ?pp=true&alt=json
headers = authorization: Bearer ya..ujc; accept: application/json; content-type: application/json
body = {"entries":[{"textPayload":"ログメッセージ"}],"resource":{"labels":{"instance_id":"53...46","zone":"projects/64...11/zones/asia-northeast1-c","project_id":"project-id"},"type":"gce_instance"},"labels":{"key":"value"},"logName":"projects/project-id/logs/logid"}
}
[Client Response] {
status = 200 OK
headers = content-type: application/json; charset=UTF-8; vary: Origin; vary: X-Origin; vary: Referer; content-encoding: gzip; date: Sat, 28 Oct 2017 06:20:22 GMT; server: ESF; cache-control: private; x-xss-protection: 1; mode=block; x-frame-options: SAMEORIGIN; x-content-type-options: nosniff; transfer-encoding: chunked
}
( "result" , WriteLogEntriesResponse' )
GCPのコンソール
GCPのコンソールでログを確認できた。
まとめ
今回はログできるかどうかをテストした。ログレベル、ログID、メッセージ、ラベルの連想配列を渡してログを出力する関数を作れば便利だと思うので、次はそれを作りたい。
Author And Source
この問題について(GCP上でHaskellプログラムからStackDriver Loggingにログを出力する), 我々は、より多くの情報をここで見つけました https://qiita.com/masatoko/items/bc55b1d3ae6bef69ec37著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .