Azure関数カスタムハンドラ
9775 ワード
導入
最近アジュールannounced general availability of custom handlers for Azure functions . カスタムハンドラーは、関数ホストからHTTPリクエストを受け取る軽量Webサーバーです.任意のプログラミング言語またはランタイムは、この要求を受信するWebサーバーを設定することができますカスタムハンドラとして使用することができます.この投稿では、goのカスタムハンドラを考慮し、特にこのカスタムハンドラからログオンします.
カスタムハンドラからのログの制限
カスタムハンドラを使用するにはいくつかの制限があります.ログは、公式の制限として記載されていませんが、一度はすぐにこの事実を発見する生産の実装のためのカスタムハンドラを探索を開始します.現在のソリューションでは、すべてのログを、関数のホストへの応答で返される文字列配列に格納できます.これらのログをあなたのログ先に挿入されます.
これはなぜ制限ですか?懸念される2つの主要なものがあります.
カスタムハンドラを使用するにはいくつかの制限があります.ログは、公式の制限として記載されていませんが、一度はすぐにこの事実を発見する生産の実装のためのカスタムハンドラを探索を開始します.現在のソリューションでは、すべてのログを、関数のホストへの応答で返される文字列配列に格納できます.これらのログをあなたのログ先に挿入されます.
これはなぜ制限ですか?懸念される2つの主要なものがあります.
どうやってログ?
Azureは将来のカスタムハンドラのログ機能を拡張しますが、それまでのオプションは何ですか?
stdOUTへのログはまだ簡単です.fmt.Println(...)
, しかし、それをすることはログがあなたがそうしなければならない何らかの文脈を失うでしょう.どのようなコンテキストですか?例えば、ログを作成した関数の呼び出しIDと名前.
ログメッセージが既知の形式に従っている場合は、ログ配列のソリューションを使用してメッセージフィールドを検索してログを検索できます.あなたのログがJSON構造化されているならば、あなたは構文解析を扱うためにKusto質問言語で機能を使用することができます、そして、これは私が下でテキストで示すものです.
カスタムJSONログの使用例
このサンプルの完全なコードはhttps://github.com/mattias-fjellstrom/go-custom-handler-logging . このサンプルではenableForwardingHttpRequest
to true
, そして、これは関数ホストがHTTPリクエストを私のハンドラに転送せずに転送することを意味します.
マイエントリーポイントmain.go
このように見える
package main
import (
"log"
"net/http"
"os"
"github.com/mattias-fjellstrom/go-custom-handler/src/handlers"
)
func main() {
port, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
if !exists {
port = "8080"
}
mux := http.NewServeMux()
mux.HandleFunc("/api/greeting", handlers.GreetingHandler)
log.Fatal(http.ListenAndServe(":"+port, mux)
}
と私のカスタムロガーを初期化するハンドラ関数
package handlers
import (
"net/http"
"time"
"encoding/json"
"github.com/mattias-fjellstrom/go-custom-handler-logging/src/logging"
)
// GreetingHandler handles GET requests to /api/greeting
func GreetingHandler(w http.ResponseWriter, r *http.Request) {
logger := logging.NewLogger()
logger.Info("Log before a five seconds sleep")
time.Sleep(5 * time.Second)
logger.Info("Log after a five seconds sleep")
logger.Warning("This is a warning log")
logger.Error("This is an error log")
response := "Hello!"
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
最後に私のカスタムロガーは
package logging
import (
"time"
"github.com/sirupsen/logrus"
)
func NewLogger() logrus.FieldLogger {
logger := logrus.New()
logger.SetLevel(logrus.InfoLevel)
jsonFormatter := logrus.JSONFormatter{
TimestampFormat: time.RFC3339Nano,
FieldMap: logrus.FieldMap{
logrus.FieldKeyTime: "timestamp",
logrus.FieldKeyMsg: "message",
logrus.FieldKeyLevel: "level",
},
}
logger.SetFormatter(&jsonFormatter)
return logger
}
Azure関数の優れたVSコード拡張を使用してこの関数を展開します.展開されると、数回呼び出し、アプリケーションの洞察リソースに頭を向け、次のクエリを実行します
traces
| where message startswith "{"
| extend d=parse_json(message)
| project d.timestamp, d.level, d.message
The where message startswith "{"
文はJSONとしてログオンされるメッセージを含む簡単な方法です.ホストがいくつかのJSONメッセージをログに記録するので、それは理想的ではありません.The extend d=parse_json(message)
文読み込みmessage
JSONとしてのフィールドproject
JSON LOGオブジェクトからフィールドを指定します.サンプル応答は以下のイメージに示されます
私たちは、上記の制限の両方に解決策を持っているという結果から明らかです.私たちは、必要なフィールドを作り、ログ間の相対的な時間を保存することができます.ログ形式を拡張して、必要なコンテキストを取得できます.
Reference
この問題について(Azure関数カスタムハンドラ), 我々は、より多くの情報をここで見つけました
https://dev.to/mattiasfjellstrom/azure-functions-custom-handlers-in-go-logging-31bp
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
このサンプルの完全なコードはhttps://github.com/mattias-fjellstrom/go-custom-handler-logging . このサンプルでは
enableForwardingHttpRequest
to true
, そして、これは関数ホストがHTTPリクエストを私のハンドラに転送せずに転送することを意味します.マイエントリーポイント
main.go
このように見えるpackage main
import (
"log"
"net/http"
"os"
"github.com/mattias-fjellstrom/go-custom-handler/src/handlers"
)
func main() {
port, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
if !exists {
port = "8080"
}
mux := http.NewServeMux()
mux.HandleFunc("/api/greeting", handlers.GreetingHandler)
log.Fatal(http.ListenAndServe(":"+port, mux)
}
と私のカスタムロガーを初期化するハンドラ関数package handlers
import (
"net/http"
"time"
"encoding/json"
"github.com/mattias-fjellstrom/go-custom-handler-logging/src/logging"
)
// GreetingHandler handles GET requests to /api/greeting
func GreetingHandler(w http.ResponseWriter, r *http.Request) {
logger := logging.NewLogger()
logger.Info("Log before a five seconds sleep")
time.Sleep(5 * time.Second)
logger.Info("Log after a five seconds sleep")
logger.Warning("This is a warning log")
logger.Error("This is an error log")
response := "Hello!"
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
最後に私のカスタムロガーはpackage logging
import (
"time"
"github.com/sirupsen/logrus"
)
func NewLogger() logrus.FieldLogger {
logger := logrus.New()
logger.SetLevel(logrus.InfoLevel)
jsonFormatter := logrus.JSONFormatter{
TimestampFormat: time.RFC3339Nano,
FieldMap: logrus.FieldMap{
logrus.FieldKeyTime: "timestamp",
logrus.FieldKeyMsg: "message",
logrus.FieldKeyLevel: "level",
},
}
logger.SetFormatter(&jsonFormatter)
return logger
}
Azure関数の優れたVSコード拡張を使用してこの関数を展開します.展開されると、数回呼び出し、アプリケーションの洞察リソースに頭を向け、次のクエリを実行しますtraces
| where message startswith "{"
| extend d=parse_json(message)
| project d.timestamp, d.level, d.message
The where message startswith "{"
文はJSONとしてログオンされるメッセージを含む簡単な方法です.ホストがいくつかのJSONメッセージをログに記録するので、それは理想的ではありません.The extend d=parse_json(message)
文読み込みmessage
JSONとしてのフィールドproject
JSON LOGオブジェクトからフィールドを指定します.サンプル応答は以下のイメージに示されます私たちは、上記の制限の両方に解決策を持っているという結果から明らかです.私たちは、必要なフィールドを作り、ログ間の相対的な時間を保存することができます.ログ形式を拡張して、必要なコンテキストを取得できます.
Reference
この問題について(Azure関数カスタムハンドラ), 我々は、より多くの情報をここで見つけました https://dev.to/mattiasfjellstrom/azure-functions-custom-handlers-in-go-logging-31bpテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol