Parameter name | Description |
Address | Enter your log receiving interface address, for example: https://www.example.com/edgeone-logs |
File compression | To reduce the size of log content and save on traffic costs, you can enable content compression by checking Use Compress log files with gzip. EdgeOne will use the gzip format to compress and then transmit the logs, and it will add the HTTP header Content-Encoding: gzip to indicate the compression format. |
Origin authentication | When Encryption Authentication is selected, the push logs will carry authentication information for the origin server to verify, ensuring the security of the data source identity. For the authentication algorithm, see: Authentication Algorithm Reference. |
Custom HTTP header | Add the HTTP headers that need to be carried when EdgeOne initiates a request. For example: Identify the log source as EdgeOne by adding the header log-source: EdgeOne .Obtain the number of log entries pushed in each POST request by adding the header BatchSize: ${batchSize} Note If the header name you fill in is a default header carried by EdgeOne log push, such as Content-Type, the header value you specify will override the default value. |
{ "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 }
# Import modules from the Python standard libraryimport time # Used to get the current timeimport gzip # Used to handle Gzip compressed data# Import HTTPServer and BaseHTTPRequestHandler classes from the http.server modulefrom http.server import HTTPServer, BaseHTTPRequestHandlerimport json # Used to handle JSON data format# Define a class that inherits from BaseHTTPRequestHandler, used to handle HTTP requestsclass Resquest(BaseHTTPRequestHandler):# Override the do_POST method, which is called when the server receives a POST requestdef do_POST(self):# Print request header informationprint(str(self.headers))# Print the command from the HTTP request (e.g., POST)print(self.command)# Read the request body content, determining the length to read as specified in the Content-Length fieldreq_datas = self.rfile.read(int(self.headers['content-length']))try:# Attempt to decode the request body content and print itprint(req_datas.decode())except Exception as e:# If an exception occurs during decoding, print the exception informationprint(e)# Check if the request header contains Content-Encoding: gzip, if so, decompress the request bodyif self.headers['Content-Encoding'] == 'gzip':data = gzip.decompress(req_datas)# Print the decompressed gzip contentprint('---------------decompress gzip content-------------------------')print(data.decode())# Check if the request path is '/edgeone-logs', if not, return a 404 errorif self.path != '/edgeone-logs':self.send_error(404, "Page not Found!")return# If the request path is correct, prepare the response datadata = {'result_code': '1','result_desc': 'Success','timestamp': int(time.time()) # Respond with the current timestamp}# Send an HTTP response status code 200, indicating the request was successfulself.send_response(200)# Set the response header Content-type to application/jsonself.send_header('Content-type', 'application/json')# End the sending of response headersself.end_headers()# Write the response data in JSON format to the response bodyself.wfile.write(json.dumps(data).encode('utf-8'))# Check if the current script is running as the main programif __name__ == '__main__':# Define the server listening address and port. You can replace 9002 with your own porthost = ('', 9002)# Create an HTTPServer object, passing in the listening address, port, and the request handler classserver = HTTPServer(host, Resquest)# Print server startup informationprint("Starting server, listen at: %s:%s" % host)# Start the server and keep it running until externally interruptedserver.serve_forever()
auth_key
and access_key
to the request URL. The details of the signature algorithm are as follows:auth_key
and access_key
after ?
.http://DomainName[:port]/[uri]?auth_key=timestamp-rand-md5hash&access_key=SecretId
/access_log/post
.md5sum(string_to_sign)
, where string_to_sign ="uri-timestamp-rand-SecretKey"
. A verification string calculated through the MD5 algorithm, consisting of digits 0-9 and lowercase letters a-z, with a fixed length of 32 characters.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
. Split the value of auth_key to obtain timestamp
, rand
, and md5hash
. First, check whether the timestamp
has expired; the recommended expiration time is 300s
. Then assemble the encrypted string based on the aforementioned rules and use the SecretKey to construct the string to be encrypted. After encryption, compare it with the auth_key
value in the md5hash
. If they match, the authentication is successful.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("-")# Determine if the request time is within the validity periodif 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")# Retrieve the secret_key using access_key (SecretId)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:# Authentication successfulif request.headers['content-encoding'] == 'gzip':# Decompress datapass# Data processingreturn 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,}// Create system signal receiverdone := 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 is your provided SecretIdauthKeys := strings.Split(authKey, "-")if len(authKeys) == 3 {currentTimeTs := authKeys[0]// Perform timestamp validity judgmentRandNum := 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) // Convert to string for comparisonif authMd5 == md5Hash {// TODO Authentication successfulif r.Header.Get("Content-Encoding") == "gzip" {// Decompress data}// Data processing}} else {// Exception Handling}}}// Retrieve SecretKeyfunc getSecretKey(accessKey string) string {if accessKey != "" {// Retrieve Secret_Key using Access_key (SecretId)return "secret_key"}return ""}
Was this page helpful?