パラメータ名 | 説明 |
インターフェースアドレス | ログ受信インターフェースアドレスを入力してください。例えば、 https://www.example.com/edgeone-logsです。 |
コンテンツ圧縮 | ログコンテンツのサイズを削減し、トラフィックコストを節約するために、gzipを使用してログファイルを圧縮するにチェックを入れることでコンテンツ圧縮を有効にできます。EdgeOneはgzip形式でログを圧縮してから転送し、圧縮形式を示すためにHTTPヘッダー Content-Encoding: gzipを追加します。 |
オリジンサーバー認証 | 暗号化認証を選択した場合、ログをプッシュする際に認証情報を含めてオリジンサーバーに検証を依頼し、データソースの身元の安全性を保証します。認証アルゴリズムについては、認証アルゴリズム参考を参照してください。 |
カスタムHTTPリクエストヘッダー | EdgeOneがリクエストを開始する際に付与するHTTPヘッダーを追加してください。例えば、 ヘッダー log-source: EdgeOne を追加することで、ログのソースが EdgeOne であることを識別します。ヘッダー BatchSize: ${batchSize} を追加することで、各POSTリクエスト内で配信されるログ件数を取得します。説明: 入力したヘッダー名が Content-Type など EdgeOne ログ配信でデフォルトで付与されるヘッダーである場合、入力したヘッダー値がデフォルト値を上書きします。 |
{"ClientState": "CH-AH","EdgeResponseTime": 366,"RequestID": "13515444256055847385","ClientRegion": "CN","RemotePort": 443,"RequestHost": "www.tencent.com","RequestMethod": "GET","RequestUrlQueryString": "-","RequestUrl": "/en-us/about.html","RequestProtocol": "HTTP/2.0","EdgeServerID": "336d5ebc5436534e61d16e63ddfca327-d41d8cd98f00b204e9800998ecf8427e","RequestTime": "2022-07-01T02:37:13Z","EdgeCacheStatus": "-","EdgeResponseBytes": 39430,"EdgeResponseStatusCode": 200,"ClientIP": "0.0.0.0","RequestReferer": "https://www.tencent.com/","RequestUA": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1","EdgeServerIP": "0.0.0.0","RequestRange": "0-100/200","EdgeInternalTime": 334,"RequestBytes": 237}
# Python標準ライブラリのモジュールをインポートします。import time # 現在時刻を取得するために使用します。import gzip # gzip圧縮データを処理するために使用します。# http.serverモジュールからHTTPServerおよびBaseHTTPRequestHandlerクラスをインポートします。from http.server import HTTPServer, BaseHTTPRequestHandlerimport json # JSONデータ形式を処理するために使用します。# BaseHTTPRequestHandlerを継承するクラスを定義し、HTTPリクエストを処理するために使用します。class Resquest(BaseHTTPRequestHandler):# do_POSTメソッドを書き換えます。このメソッドは、サーバーがPOSTリクエストを受信したときに呼び出されます。def do_POST(self):# リクエストヘッダー情報を出力します。print(str(self.headers))# HTTPリクエストのコマンド(例:POST)を出力します。print(self.command)# リクエストボディの内容を読み取り、リクエストヘッダーのContent-Lengthフィールドに基づいて読み取り長を決定します。req_datas = self.rfile.read(int(self.headers['content-length']))try:# リクエストボディの内容をデコードして出力することを試みます。print(req_datas.decode())except Exception as e:# デコード中に例外が発生した場合、例外情報を出力します。print(e)# リクエストヘッダーにContent-Encoding: gzipがあるかどうかを確認し、ある場合はリクエストボディを解凍します。`self.headers.get('Content-Encoding')`data = gzip.decompress(req_datas)# 解凍後のgzipコンテンツを出力します。print('---------------decompress gzip content-------------------------')print(data.decode())# リクエストのパスが「/edgeone-logs」であるかどうかを確認し、そうでない場合は404エラーを返します。if self.path != '/edgeone-logs':self.send_error(404, "Page not Found!")return# リクエストパスが正しい場合、レスポンスデータを準備します。data = {'result_code': '1','result_desc': 'Success','timestamp': int(time.time()) # 応答の現在のタイムスタンプ}# HTTPレスポンスステータスコード200を送信し、リクエストが成功したことを示します。self.send_response(200)# レスポンスヘッダーのContent-typeをapplication/jsonに設定します。self.send_header('Content-type', 'application/json')# レスポンスヘッダーの送信を終了します。self.end_headers()# レスポンスデータをJSON形式でレスポンスボディに書き込みます。self.wfile.write(json.dumps(data).encode('utf-8'))# 現在のスクリプトがメインプログラムとして実行されているかどうかを確認します。if __name__ == '__main__':# サーバーがリッスンするアドレスとポートを定義します。9002をカスタムポートに置き換えることができます。host = ('', 9002)# HTTPServerオブジェクトを作成し、リッスンアドレスとポート、およびリクエスト処理を行うリクエストハンドラクラスを渡します。server = HTTPServer(host, Resquest)# サーバー起動情報を出力します。print("Starting server, listen at: %s:%s" % host)# サーバーを起動し、外部から中断されるまで継続的に実行します。server.serve_forever()
auth_keyとaccess_keyを追加します。署名アルゴリズムの詳細は以下の通りです:?の後にauth_keyとaccess_keyが付加されます。http://DomainName[:port]/[uri]?auth_key=timestamp-rand-md5hash&access_key=SecretId
/access_log/postです。md5sum(string_to_sign)です。ここで、string_to_sign ="uri-timestamp-rand-SecretKey"です。md5アルゴリズムで計算された検証文字列であり、数字0-9と小文字の英字a-zが混在し、固定長は32文字です。https://www.example.com/access_log/postYourIDYourKey/access_log/post15715872000string_to_sign = "/access_log/post-1571587200-0-YourKey"
md5hash=md5sum("/access_log/post-1571587200-0-YourKey")=1f7ffa7bff8f06bbfbe2ace0f14b7e16
https://www.example.com/access_log/post?auth_key=1571587200-0-1f7ffa7bff8f06bbfbe2ace0f14b7e16&access_key=YourID
auth_keyの値を抽出します。auth_keyの値を分割し、timestampとrandとmd5hashを取得します。まずtimestampが期限切れかどうかを確認できます。期限切れ時間は300sを推奨します。そして、上記のルールに基づいて暗号化文字列を組み立て、SecretKeyを利用して暗号化する必要がある文字列を組み立てます。暗号化後、auth_key内のmd5hash値と比較し、同じであれば認証が成功したことを示します。import hashlibfrom flask import Flask, requestapp = Flask(__name__)def get_rsp(msg, result={}, code=0):return {"respCode": code,"respMsg": msg,"result": result}def get_secret_key(access_key):return "secret_key"@app.route("/access_log/post", methods=['POST'])def access_log():if request.method == 'POST':if request.content_type.startswith('application/json'):current_time_ts, rand_num, md5hash = request.args.get("auth_key").split("-")# リクエスト時間が有効期間内であるかどうかを判断します。if time.time() - int(current_time_ts) > 300:return get_rsp(msg="The request is out of time", code=-1)access_key = request.args.get("access_key")# access_key(SecretId)でsecret_keyを取得します。secret_key = get_secret_key(access_key)raw_str = "%s-%s-%s-%s" % (request.path, current_time_ts, rand_num, secret_key)auth_md5hash = hashlib.md5(raw_str.encode("utf-8")).hexdigest()if auth_md5hash == md5hash:# 認証に成功しました。if request.headers['content-encoding'] == 'gzip':# データを解凍します。pass# データ処理return get_rsp("ok")return get_rsp(msg="Please use content_type by application/json", code=-1)return get_rsp(msg="The request method not find, method == %s" % request.method, code=-1)if __name__ == '__main__':app.run(host='0.0.0.0', port=8888, debug=True)
package mainimport ("context""crypto/md5""fmt""log""net/http""os""os/signal""strings""syscall")func main() {mux := http.NewServeMux()mux.Handle("/access_log/post", &logHandler{})server := &http.Server{Addr: ":5000",Handler: mux,}done := make(chan os.Signal)signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)go func() {<-doneif err := server.Shutdown(context.Background()); err != nil {log.Fatal("Shutdown server:", err)}}()err := server.ListenAndServe()if err != nil {if err == http.ErrServerClosed {log.Print("Server closed under request")} else {log.Fatal("Server closed unexpected")}}}type logHandler struct{}func (*logHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {if r.Method == "POST" {query := r.URL.Query()authKey := query.Get("auth_key")accessKey := query.Get("access_key")//access_keyはお客様が提供するSecretIdです。authKeys := strings.Split(authKey, "-")if len(authKeys) == 3 {currentTimeTs := authKeys[0]//タイムスタンプの有効期限を判断します。RandNum := authKeys[1]md5Hash := authKeys[2]secretKey := getSecretKey(accessKey)authStr := fmt.Sprintf("%s-%s-%s-%s", "/access_log/post", currentTimeTs, RandNum, secretKey)data := []byte(authStr)has := md5.Sum(data)authMd5 := fmt.Sprintf("%x", has) //文字列に変換して比較します。if authMd5 == md5Hash {// todo 認証に成功しました。if r.Header.Get("Content-Encoding") == "gzip" {//データを解凍します。}//データ処理}} else {//異常処理}}}// SecretKeyを取得します。func getSecretKey(accessKey string) string {if accessKey != "" {// Access_key(SecretI)でSecret_Keyを取得します。return "secret_key"}return ""}
フィードバック