studia/jezyki-skryptowe/lista5/main.py
2024-06-14 16:53:58 +02:00

129 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import logging
from logger import logger
import log_statistics
import reader
import parser
import argparse
from enum import StrEnum
class Commands(StrEnum):
PARSE = "parse"
IPV4 = "ipv4",
USER = "user",
TYPE = "type",
RANDOM = "random",
DURATION = "duration",
FREQ = "freq"
def main(args):
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.addFilter(lambda log: log.levelno <= logging.WARNING)
stdout_handler.setLevel(logging.DEBUG)
stdout_handler.setFormatter(logging.Formatter('%(levelname)s - %(name)s - %(message)s'))
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.ERROR)
stderr_handler.setFormatter(logging.Formatter('%(levelname)s - %(name)s - %(message)s'))
logger.addHandler(stdout_handler)
logger.addHandler(stderr_handler)
if args.log_level == "NONE":
logger.disabled = True
else:
logger.setLevel(args.log_level)
try:
logs = reader.read_logs(args.filename)
except:
logger.critical(f"Could not open file {args.filename}")
exit(1)
if args.subcommand == Commands.PARSE:
for line in logs:
print(f"{line.timestamp.strftime('%d/%m:%H:%M:%S')};{line.hostname};{line.pid};{line.message}")
#1.1.2
if args.subcommand == Commands.IPV4:
for line in logs:
print(*parser.get_ipv4s_from_log(line), sep=", ")
#1.1.3
elif args.subcommand == Commands.USER:
for line in logs:
print(parser.get_user_from_log(line) or "")
#1.1.4
elif args.subcommand == Commands.TYPE:
for line in logs:
print(parser.get_message_type(line.message))
#1.3.1
elif args.subcommand == Commands.RANDOM:
random_logs = log_statistics.random_user_logs(list(logs), args.n)
for line in random_logs:
print(line.original_line)
#1.3.2
elif args.subcommand == Commands.DURATION:
log_list = list(logs)
if args.group_by_users:
durations_by_user = log_statistics.get_average_session_duration_by_user(log_list)
for (username, (avg_time, stdev)) in sorted(durations_by_user.items(), key=lambda x: x[1], reverse=True):
print(f"{username}: average={avg_time:.4f}s, stdev={stdev:.4f}s")
else:
(avg_time, stdev) = log_statistics.get_average_session_duration(log_list)
print(f"average={avg_time:.4f}s, stdev={stdev:.4f}s")
#1.3.3
elif args.subcommand == Commands.FREQ:
log_list = list(logs)
(most, least) = log_statistics.get_most_and_least_frequent_user(log_list)
if most and least:
print(f"most frequent user - {most[0]} - {most[1]} login(s)")
print(f"least frequent user - {least[0]} - {least[1]} login(s)")
else:
print("could not determine most and least frequent user")
def positive_int(arg):
try:
val = int(arg)
except ValueError:
raise argparse.ArgumentTypeError("Must be an integer")
if val < 0:
raise argparse.ArgumentTypeError("Must be greater than or equal to 0")
return val
def parse_args():
parser = argparse.ArgumentParser(description="Script for analyzing sshd logs")
#1.4.1
parser.add_argument("filename", help="Path of the file to be read")
#1.4.2
parser.add_argument("--log-level", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "NONE"], default="INFO", help="Level of logging, default is info")
#1.4.3
subparsers = parser.add_subparsers(dest="subcommand", title="subcommands", required=True)
subparsers.add_parser(Commands.PARSE, help="Parse logs into semicolon separated structure")
subparsers.add_parser(Commands.IPV4, help="Get all IPv4 addresses from log messsages")
subparsers.add_parser(Commands.USER, help="Extract user from log messages")
subparsers.add_parser(Commands.TYPE, help="Get type of log message")
random_parser = subparsers.add_parser(Commands.RANDOM, help="Get specified amount (default is 3) of random logs from random user")
random_parser.add_argument("-n", type=positive_int, default=3, help="Amount of random logs to be returned")
duration_parser = subparsers.add_parser(Commands.DURATION, help="Get average session duration and standard deviation")
duration_parser.add_argument("--group-by-users", action="store_true", help="Whether session durations should be calculated for each user separately")
subparsers.add_parser(Commands.FREQ, help="Get most and least frequently logging users")
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
main(args)