Skip to content

Commit

Permalink
Messages actually match with the status codes
Browse files Browse the repository at this point in the history
  • Loading branch information
sd416 committed Jun 17, 2024
1 parent 35bda79 commit 4c50e89
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 31 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The script is configured through the following parameters. Modify the configurat
- `write_to_file`: Flag to indicate if logs should be written to a file (`True` or `False`).
- `log_file_path`: File path for log output (if `write_to_file` is `True`).
- `http_format_logs`: Flag to format logs in HTTP response-like format (`True` or `False`).
- `custom_app_names`: List of custom application names to be included in log messages.


## Example Configuration Parameters

Expand All @@ -42,6 +44,7 @@ rate_change_max_percentage = 0.3 # Maximum percentage change in the log generat
write_to_file = True # Flag to indicate if logs should be written to a file
log_file_path = 'logs.txt' # File path for log output
http_format_logs = False # Flag to format logs in HTTP response-like format
custom_app_names = ['App1', 'App2', 'App3'] # List of custom application names
```


Expand Down
47 changes: 31 additions & 16 deletions log_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
log_file_path = 'logs.txt' # File path for log output
http_format_logs = True # Flag to format logs in HTTP response-like format
stop_after_seconds = -1 # Stop the script after X seconds (default -1 for continuous)
custom_app_names = [] # List of custom application names

log_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR']
log_messages = [
Expand Down Expand Up @@ -73,21 +74,36 @@
'User account unlocked'
]

http_status_codes = ['200 OK', '201 Created', '204 No Content', '400 Bad Request', '401 Unauthorized', '403 Forbidden', '404 Not Found', '500 Internal Server Error', '502 Bad Gateway', '503 Service Unavailable']
http_status_codes = {
'200 OK': ['User login successful', 'Data fetched successfully', 'User logged out', 'Service started', 'Service stopped', 'Configuration updated', 'Data processed successfully', 'Database connection established', 'Cache cleared', 'Scheduled task started', 'Scheduled task completed', 'Backup completed successfully', 'Session token refreshed', 'New user registered', 'Password change requested', 'Password change successful', 'API request received', 'API response sent', 'Service health check passed', 'Application deployment started', 'Application deployment completed', 'Application rollback initiated', 'Application rollback completed', 'File uploaded successfully', 'User profile updated', 'Email sent successfully', 'SMS sent successfully', 'Payment transaction completed', 'User account unlocked'],
'400 Bad Request': ['Invalid user input detected', 'Configuration validation error', 'Credit card validation error'],
'401 Unauthorized': ['User login failed', 'Permission denied'],
'403 Forbidden': ['Permission denied'],
'404 Not Found': ['File not found'],
'500 Internal Server Error': ['Error fetching data from database', 'Unexpected error occurred', 'Resource allocation failure', 'Database connection lost', 'Cache update failed', 'Backup failed', 'Password change failed', 'Service health check failed', 'File upload failed', 'User profile update failed', 'Email delivery failed', 'SMS delivery failed', 'Payment transaction failed', 'User account locked']
}

def generate_log_line(http_format_logs=http_format_logs):
def generate_log_line(http_format_logs=http_format_logs, custom_app_names=custom_app_names):
"""Generate a single log line with a timestamp and realistic message."""
timestamp = datetime.datetime.utcnow().isoformat() + 'Z'
log_level = random.choice(log_levels)
message = random.choice(log_messages)

if custom_app_names:
app_name = random.choice(custom_app_names)
message = f"{app_name}: {message}"

if http_format_logs:
status_code = random.choice(http_status_codes)
for status_code, messages in http_status_codes.items():
if message in messages:
return f"{timestamp} {log_level} HTTP/1.1 {status_code} {message}"
# Fallback in case message does not match any status code
status_code = random.choice(list(http_status_codes.keys()))
return f"{timestamp} {log_level} HTTP/1.1 {status_code} {message}"
else:
return f"{timestamp} {log_level} {message}"

def write_logs(rate, duration, log_file=None, http_format_logs=http_format_logs):
def write_logs(rate, duration, log_file=None, http_format_logs=http_format_logs, custom_app_names=custom_app_names):
"""Write logs at a specified rate for a given duration."""
end_time = time.time() + duration
bytes_per_second = int(rate * 1024 * 1024)
Expand All @@ -96,7 +112,7 @@ def write_logs(rate, duration, log_file=None, http_format_logs=http_format_logs)
while time.time() < end_time:
start_time = time.time()
for _ in range(int(lines_per_second)):
log_line = generate_log_line(http_format_logs)
log_line = generate_log_line(http_format_logs, custom_app_names)
if log_file:
log_file.write(f"{log_line}\n")
else:
Expand All @@ -105,7 +121,7 @@ def write_logs(rate, duration, log_file=None, http_format_logs=http_format_logs)
time_to_sleep = max(0, 1 - elapsed_time)
time.sleep(time_to_sleep)

def write_logs_random_rate(duration, rate_min, rate_max, log_file=None, http_format_logs=http_format_logs):
def write_logs_random_rate(duration, rate_min, rate_max, log_file=None, http_format_logs=http_format_logs, custom_app_names=custom_app_names):
"""Write logs at a random rate between rate_min and rate_max for a given duration."""
end_time = time.time() + duration
remaining_time = duration
Expand All @@ -118,10 +134,10 @@ def write_logs_random_rate(duration, rate_min, rate_max, log_file=None, http_for
while remaining_time > 0:
segment_duration = random.uniform(1, remaining_time)
rate = random.uniform(rate_min, rate_max)
write_logs(rate, segment_duration, log_file, http_format_logs)
write_logs(rate, segment_duration, log_file, http_format_logs, custom_app_names)
remaining_time -= segment_duration

def write_logs_random_segments(total_duration, segment_max_duration, rate_min, rate_max, base_exit_probability, log_file=None, http_format_logs=http_format_logs):
def write_logs_random_segments(total_duration, segment_max_duration, rate_min, rate_max, base_exit_probability, log_file=None, http_format_logs=http_format_logs, custom_app_names=custom_app_names):
"""Write logs in random segments with a chance to exit early."""
remaining_time = total_duration
while remaining_time > 0:
Expand All @@ -130,27 +146,26 @@ def write_logs_random_segments(total_duration, segment_max_duration, rate_min, r
print("Exiting early based on random exit clause.")
return
segment_duration = random.uniform(1, min(segment_max_duration, remaining_time))
write_logs_random_rate(segment_duration, rate_min, rate_max, log_file, http_format_logs)
write_logs_random_rate(segment_duration, rate_min, rate_max, log_file, http_format_logs, custom_app_names)
remaining_time -= segment_duration

def main(duration_normal, duration_peak, rate_normal_min, rate_normal_max, rate_peak, log_line_size, base_exit_probability, rate_change_probability, rate_change_max_percentage, write_to_file, log_file_path, http_format_logs, stop_after_seconds):
def main(duration_normal, duration_peak, rate_normal_min, rate_normal_max, rate_peak, log_line_size, base_exit_probability, rate_change_probability, rate_change_max_percentage, write_to_file, log_file_path, http_format_logs, stop_after_seconds, custom_app_names):
start_time = time.time()
if write_to_file:
with open(log_file_path, 'w') as log_file:
while stop_after_seconds == -1 or time.time() - start_time < stop_after_seconds:
# Normal logging period with random segments
write_logs_random_segments(duration_normal, 5, rate_normal_min, rate_normal_max, base_exit_probability, log_file, http_format_logs) # segments up to 5 seconds
write_logs_random_segments(duration_normal, 5, rate_normal_min, rate_normal_max, base_exit_probability, log_file, http_format_logs, custom_app_names) # segments up to 5 seconds

# Peak logging period
write_logs_random_rate(duration_peak, rate_normal_max, rate_peak, log_file, http_format_logs)
write_logs_random_rate(duration_peak, rate_normal_max, rate_peak, log_file, http_format_logs, custom_app_names)
else:
while stop_after_seconds == -1 or time.time() - start_time < stop_after_seconds:
# Normal logging period with random segments
write_logs_random_segments(duration_normal, 5, rate_normal_min, rate_normal_max, base_exit_probability, None, http_format_logs) # segments up to 5 seconds
write_logs_random_segments(duration_normal, 5, rate_normal_min, rate_normal_max, base_exit_probability, None, http_format_logs, custom_app_names) # segments up to 5 seconds

# Peak logging period
write_logs_random_rate(duration_peak, rate_normal_max, rate_peak, None, http_format_logs)
write_logs_random_rate(duration_peak, rate_normal_max, rate_peak, None, http_format_logs, custom_app_names)

if __name__ == "__main__":
main(duration_normal, duration_peak, rate_normal_min, rate_normal_max, rate_peak, log_line_size, base_exit_probability, rate_change_probability, rate_change_max_percentage, write_to_file, log_file_path, http_format_logs, stop_after_seconds)

main(duration_normal, duration_peak, rate_normal_min, rate_normal_max, rate_peak, log_line_size, base_exit_probability, rate_change_probability, rate_change_max_percentage, write_to_file, log_file_path, http_format_logs, stop_after_seconds, custom_app_names)
26 changes: 11 additions & 15 deletions test_log_generator.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,45 @@
import pytest
import time
from log_generator import (
generate_log_line,
write_logs,
write_logs_random_rate,
write_logs_random_segments,
main
)
from log_generator import generate_log_line, write_logs, write_logs_random_rate, write_logs_random_segments, main

# Override the configurations for testing
test_duration_normal = 2 # seconds
test_duration_peak = 1 # seconds
test_duration_normal = 5 # seconds
test_duration_peak = 2 # seconds
test_rate_normal_min = 0.0001 # MB/s
test_rate_normal_max = 0.001 # MB/s
test_rate_peak = 0.002 # MB/s
test_log_line_size = 50 # Average size of a log line in bytes
test_base_exit_probability = 0.1 # Base 10% chance to exit early
test_rate_change_probability = 0.2 # 20% chance to change rate_max
test_rate_change_max_percentage = 0.1 # Maximum 10% change in rate_max
test_stop_after_seconds = 2 # Stop the script after 2 seconds for testing
test_stop_after_seconds = 21 # Stop the script after 21 seconds (3 Iterations) for testing
test_custom_app_names = ['App1', 'App2', 'App3']

def test_generate_log_line():
print("Testing generate_log_line")
log_line = generate_log_line(http_format_logs=False)
log_line = generate_log_line(http_format_logs=False, custom_app_names=test_custom_app_names)
assert log_line is not None
assert len(log_line) > 0

def test_write_logs(tmp_path):
print("Testing write_logs")
log_file_path = tmp_path / "test_logs.txt"
with open(log_file_path, 'w') as log_file:
write_logs(test_rate_normal_min, test_duration_normal, log_file, http_format_logs=False)
write_logs(test_rate_normal_min, test_duration_normal, log_file, http_format_logs=False, custom_app_names=test_custom_app_names)
assert log_file_path.read_text().strip() != ""

def test_write_logs_random_rate(tmp_path):
print("Testing write_logs_random_rate")
log_file_path = tmp_path / "test_logs_random_rate.txt"
with open(log_file_path, 'w') as log_file:
write_logs_random_rate(test_duration_peak, test_rate_normal_min, test_rate_normal_max, log_file, http_format_logs=False)
write_logs_random_rate(test_duration_peak, test_rate_normal_min, test_rate_normal_max, log_file, http_format_logs=False, custom_app_names=test_custom_app_names)
assert log_file_path.read_text().strip() != ""

def test_write_logs_random_segments(tmp_path):
print("Testing write_logs_random_segments")
log_file_path = tmp_path / "test_logs_random_segments.txt"
with open(log_file_path, 'w') as log_file:
write_logs_random_segments(test_duration_normal, 1, test_rate_normal_min, test_rate_normal_max, test_base_exit_probability, log_file, http_format_logs=False)
write_logs_random_segments(test_duration_normal, 1, test_rate_normal_min, test_rate_normal_max, test_base_exit_probability, log_file, http_format_logs=False, custom_app_names=test_custom_app_names)
assert log_file_path.read_text().strip() != ""

def test_main(tmp_path):
Expand All @@ -52,7 +48,7 @@ def test_main(tmp_path):
start_time = time.time()
timeout = 10 # seconds
while time.time() - start_time < timeout:
main(test_duration_normal, test_duration_peak, test_rate_normal_min, test_rate_normal_max, test_rate_peak, test_log_line_size, test_base_exit_probability, test_rate_change_probability, test_rate_change_max_percentage, True, str(log_file_path), False, test_stop_after_seconds)
main(test_duration_normal, test_duration_peak, test_rate_normal_min, test_rate_normal_max, test_rate_peak, test_log_line_size, test_base_exit_probability, test_rate_change_probability, test_rate_change_max_percentage, True, str(log_file_path), False, test_stop_after_seconds, test_custom_app_names)
if log_file_path.read_text().strip() != "":
break
assert log_file_path.read_text().strip() != ""

0 comments on commit 4c50e89

Please sign in to comment.