Testing Logging with HTTP and Python


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


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.



The Python script provided makes the following assumptions:

  1. You have Ngrok installed
  2. There are no other Ngrok servers currently running on your machine
  3. 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_header("Content-type", "application/stream+json")
        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
        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)
        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}")

    except KeyboardInterrupt:

    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.