Testing Logging with HTTP and Python
Overview
This section describes how to locally test Sym's HTTP Logging. To do this, we will:
- Set up a local Python server that accepts POST requests and expose the server via Ngrok
- Add the Ngrok URL to your
sym_log_destination
resource - View log entries in the console
Instructions
Set up the Python Server
Download the following Python script, which will start a local Python server on port 8080 and set up an Ngrok endpoint that points to it, so that the server is accessible from the public internet.
Prerequisites
The Python script provided makes the following assumptions:
- You have Ngrok installed
- There are no other Ngrok servers currently running on your machine
- Port 8080 is free
# Python 3 server for Sym Log Entries
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
import subprocess
import urllib.request
hostName = "localhost"
serverPort = 8080
class SymHTTPLogDestination(BaseHTTPRequestHandler):
def do_GET(self):
"""GET localhost:8080
Displays the received log entries in JSON format.
"""
self.send_response(200)
self.send_header("Content-type", "application/stream+json")
self.end_headers()
with open("logs.txt", mode='r', encoding='utf-8') as f:
content = f.read()
content = content.rstrip(",\n")
self.wfile.write(bytes(f"[{content}]", 'utf-8'))
def do_POST(self):
"""POST localhost:8080
Receives Sym Log entries, prints them to the console, and saves them to logs.txt
"""
self.send_response(200)
self.end_headers()
content_len = int(self.headers.get('Content-Length'))
post_body = self.rfile.read(content_len)
json_post_body = json.loads(post_body.decode('utf-8'))
with open("logs.txt","a", encoding='utf-8') as file:
json.dump(json_post_body, file, indent=4)
file.write(",\n")
print(json.dumps(json_post_body, indent=4))
if __name__ == "__main__":
# Start the Python web server at localhost:8080
webServer = HTTPServer((hostName, serverPort), SymHTTPLogDestination)
# Set up ngrok to forward requests to localhost:8080
p = subprocess.Popen([f"ngrok http {str(serverPort)}"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Grab the Ngrok public url
contents = urllib.request.urlopen("http://localhost:4040/api/tunnels").read()
ngrok_url = json.loads(contents)["tunnels"][0]["public_url"]
print(f"HTTP Log Destination URL: {ngrok_url}")
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
p.kill()
print("Server stopped.")
Now, run the script from your preferred terminal.
python3 log_server.py
Terraform the HTTP Log Destination
The Python script will print out the Ngrok domain, e.g. (https://99f07bccd804.ngrok.io
).
Copy this URL, and use it in your sym_log_destination
resource.
resource "sym_log_destination" "local" {
type = "http"
settings = {
# Paste the output of your script here
url = "https://99f07bccd804.ngrok.io"
}
}
Then add the log destination to the log_destination_ids
in your sym_environment
resource.
resource "sym_environment" "test" {
name = "test-logging"
log_destination_ids = [sym_log_destination.http.id]
}
Test the Log Destination
Now that your Ngrok server is running and your environment is sending logs to it, any requests you make with /sym
will audit a corresponding log entry! These log entries will be printed to the console and saved to a file called logs.txt
.
You may also view the logs in a browser if you navigate to localhost:8080
.
Updated 4 months ago