diff options
Diffstat (limited to 'awk/rawk/example.rawk')
-rw-r--r-- | awk/rawk/example.rawk | 276 |
1 files changed, 179 insertions, 97 deletions
diff --git a/awk/rawk/example.rawk b/awk/rawk/example.rawk index 5bd1919..950f5e9 100644 --- a/awk/rawk/example.rawk +++ b/awk/rawk/example.rawk @@ -1,100 +1,182 @@ -# rawk Example Program -# This demonstrates various features of the rawk language + # Main processing pipeline + BEGIN { + print "Apache Log Analysis Report" + print "=============================" + print "" + } -# Basic single-line functions -$add = (x, y) -> x + y; -$multiply = (a, b) -> a * b; -$greet = (name) -> "Hello, " name "!"; + RAWK { + # Helper functions for parsing and analysis + $extract_method = (request) -> { + split(request, parts, " ") + return parts[1] + }; + + $extract_url = (request) -> { + split(request, parts, " ") + return parts[2] + }; + + $format_error_report = (ip, status, url, user_agent) -> { + return ip " - " status " - " url " (" user_agent ")" + }; + + $format_success_report = (ip, method, url, bytes) -> { + return ip " - " method " " url " (" bytes " bytes)" + }; + + $is_success = (status) -> { + return status >= 200 && status < 300 + }; + + $is_api_request = (url) -> { + return index(url, "/api/") > 0 + }; + + $is_large_request = (bytes) -> { + return bytes > 1048576 # 1MB + }; + + # Functional programming examples + $extract_endpoint = (url) -> { + return url + }; + + $extract_bot_components = (user_agent, result) -> { + split(user_agent, result, " ") + return length(result) + }; + } -# Multi-line function with complex logic -$calculate_stats = (numbers, result, i, sum, count, max, min) -> { - sum = 0 - count = 0 - max = 0 - min = 0 - first = 1 - - for (i in numbers) { - sum += numbers[i] - count++ - if (first || numbers[i] > max) { - max = numbers[i] - } - if (first || numbers[i] < min) { - min = numbers[i] - } - first = 0 - } - - result["sum"] = sum - result["count"] = count - result["average"] = count > 0 ? sum / count : 0 - result["max"] = max - result["min"] = min - - return count -}; + # Process each log line + { + # Parse Apache log format: IP - - [timestamp] "method url status" bytes "referer" "user-agent" + # Note that we use a series of simpler regex matches, rather than trying to do it all at once + if (match($0, /^([0-9.]+)/)) { + ip = substr($0, RSTART, RLENGTH) + + # Extract request (method url protocol) + if (match($0, /"([^"]+)"/)) { + request = substr($0, RSTART + 1, RLENGTH - 2) + # Extract method and URL from request + method = extract_method(request) + url = extract_url(request) + } + + # Extract status code (number after the request) + if (match($0, /" ([0-9]+) /)) { + status = substr($0, RSTART + 1, RLENGTH - 2) + # Remove leading/trailing spaces + gsub(/^[ \t]+|[ \t]+$/, "", status) + } + + # Extract bytes (number after request) + if (match($0, /" ([0-9]+) /)) { + bytes = substr($0, RSTART + 1, RLENGTH - 2) + } + + # Extract user agent (last quoted field) + if (match($0, /"([^"]*)"$/)) { + user_agent = substr($0, RSTART + 1, RLENGTH - 2) + } + + # Store for analysis + request_count++ + + # Real-time processing using some standard library predicates + if (http_is_server_error(status)) { + server_error_count++ + error_report = format_error_report(ip, status, url, user_agent) + print "SERVER ERROR: " error_report + } else if (http_is_client_error(status)) { + client_error_count++ + error_report = format_error_report(ip, status, url, user_agent) + print "CLIENT ERROR: " error_report + } else if (is_success(status)) { + success_count++ + success_report = format_success_report(ip, method, url, bytes) + print "✓ " success_report + } + + # Track different types of requests + if (is_api_request(url)) { + api_count++ + api_urls[api_count] = url + } + + if (url_is_static_file(url)) { + static_count++ + static_urls[static_count] = url + } + + if (http_is_mutating_method(method)) { + mutation_count++ + if (ip_is_public(ip)) { + print "EXTERNAL MUTATION: " ip " " method " " url + } + } + + # Track user types + if (is_bot(user_agent)) { + bot_count++ + bot_agents[bot_count] = user_agent + } else if (user_agent_is_mobile(user_agent)) { + mobile_count++ + } else if (user_agent_is_desktop(user_agent)) { + desktop_count++ + } + + # Track large requests + if (is_large_request(bytes)) { + large_count++ + large_urls[large_count] = url + } + } + } -# Function that calls other functions -$process_data = (data) -> { - calculate_stats(data, stats) - formatted = "Sum: " stats["sum"] ", Avg: " stats["average"] - return formatted -}; - -# Main program -BEGIN { - print "=== rawk Example Program ===" - - # Test basic functions - print "Basic functions:" - print " add(5, 3) =", add(5, 3) - print " multiply(4, 7) =", multiply(4, 7) - print " greet(\"World\") =", greet("World") - - # Test nested function calls - print "\nNested function calls:" - print " add(multiply(2, 3), 5) =", add(multiply(2, 3), 5) - - # Test data processing - print "\nData processing:" - data[1] = 10 - data[2] = 20 - data[3] = 30 - data[4] = 40 - data[5] = 50 - - result = process_data(data) - print " " result - - # Test array utilities - print "\nArray utilities:" - info["name"] = "rawk" - info["type"] = "language" - info["target"] = "awk" - - key_count = keys(info) - value_count = values(info) - get_keys(info, key_list) - get_values(info, value_list) - - print " Key count:", key_count - print " Value count:", value_count - print " Keys:", key_list[1], key_list[2], key_list[3] - print " Values:", value_list[1], value_list[2], value_list[3] -} - -# Process input lines (if any) -{ - processed = "Line " NR ": " $0 - if (length($0) > 20) { - print processed " (long)" - } else { - print processed " (short)" - } -} - -END { - print "\n=== Program Complete ===" - print "Total lines processed:", NR -} \ No newline at end of file + END { + print "" + print "Summary Statistics" + print "====================" + print "Total Requests:", request_count + print "Successful:", success_count + print "Client Errors:", client_error_count + print "Server Errors:", server_error_count + print "Total Errors:", client_error_count + server_error_count + print "Error Rate:", sprintf("%.2f%%", ((client_error_count + server_error_count) / request_count) * 100) + print "API Requests:", api_count + print "Static Files:", static_count + print "Mutating Requests:", mutation_count + print "Mobile Users:", mobile_count + print "Desktop Users:", desktop_count + print "Bot Requests:", bot_count + print "Large Requests (>1MB):", large_count + + # Some functional patterns at play, map, flatMap, and take. + if (api_count > 0) { + print "" + print "API Usage Analysis" + print "====================" + + # Use map to extract API endpoints + endpoint_count = map("extract_endpoint", api_urls, endpoints) + print "API Endpoints found:", endpoint_count + } + + if (bot_count > 0) { + print "" + print "Bot Activity Analysis" + print "========================" + + # Use flatMap to extract bot user agent components + bot_components_count = flatMap("extract_bot_components", bot_agents, bot_components) + print "Bot components analyzed:", bot_components_count + + # Use take to show top 3 bot components + top_components_count = take(3, bot_components, top_components) + print "Top bot components:", top_components_count + } + + print "" + print "End analysis" + } \ No newline at end of file |