参数名称 | 说明 |
接口地址 | 填入您的日志接收接口地址,例如: 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,如果有,则解压请求体if self.headers['Content-Encoding'] == 'gzip':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/jsonself.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/post
SecretId = YourID
SecretKey = YourKey
uri = /access_log/post
timestamp = 1571587200
rand = 0
string_to_sign = "/access_log/post-1571587200-0-YourKey"
md5hash=md5sum("/access_log/post-1571587200-0-YourKey")=1f7ffa7bff8f06bbfbe2ace0f14b7e16
https://www.example.com
/cdnlog/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_keysecret_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 即您提供的SecretIdauthKeys := 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 {//异常处理}}}// 获取SecretKeyfunc getSecretKey(accessKey string) string {if accessKey != "" {// 通过Access_key(SecretI)获取Secret_Keyreturn "secret_key"}return ""}
本页内容是否解决了您的问题?