ವಿಷಯಕ್ಕೆ ತೆರಳಿ

ಪ್ರಾಜೆಕ್ಟ್ 16: ಲಾಗ್ ಫೈಲ್ ಪಾರ್ಸರ್ (Regex ಬಳಸಿ)

ಈ ಪ್ರಾಜೆಕ್ಟ್‌ನಲ್ಲಿ, ನಾವು ರೆಗ್ಯುಲರ್ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ಗಳ (Regex) ಶಕ್ತಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು ವೆಬ್ ಸರ್ವರ್ ಲಾಗ್ ಫೈಲ್ ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡುವ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ನಿರ್ಮಿಸುತ್ತೇವೆ. ಲಾಗ್ ಫೈಲ್‌ಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಅಸಂಘಟಿತ ಟೆಕ್ಸ್ಟ್ ಆಗಿರುತ್ತವೆ, ಮತ್ತು ಅವುಗಳಿಂದ ನಿರ್ದಿಷ್ಟ ಮಾಹಿತಿಯನ್ನು (ಉದಾಹರಣೆಗೆ, IP ವಿಳಾಸ, ವಿನಂತಿಯ ದಿನಾಂಕ, ಸ್ಟೇಟಸ್ ಕೋಡ್) ಹೊರತೆಗೆಯಲು Regex ಅತ್ಯಂತ ಪರಿಣಾಮಕಾರಿ ಸಾಧನವಾಗಿದೆ.

ಕಲಿಕೆಯ ಪರಿಕಲ್ಪನೆಗಳು

  • re ಮಾಡ್ಯೂಲ್‌ನ ಆಳವಾದ ಬಳಕೆ.
  • ಸಂಕೀರ್ಣ Regex ಪ್ಯಾಟರ್ನ್‌ಗಳನ್ನು ರಚಿಸುವುದು ಮತ್ತು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು.
  • ಗ್ರೂಪ್‌ಗಳನ್ನು (()) ಬಳಸಿ ನಿರ್ದಿಷ್ಟ ಡೇಟಾವನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡುವುದು.
  • ಫೈಲ್‌ಗಳನ್ನು ಲೈನ್-ಬೈ-ಲೈನ್ ಓದುವುದು.
  • ಪಾರ್ಸ್ ಮಾಡಿದ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸಲು ಲಿಸ್ಟ್‌ಗಳು ಮತ್ತು ಡಿಕ್ಷನರಿಗಳನ್ನು ಬಳಸುವುದು.
  • collections.Counter ಬಳಸಿ ಸಾರಾಂಶ ವರದಿಯನ್ನು ರಚಿಸುವುದು.

ಸ್ಯಾಂಪಲ್ ಲಾಗ್ ಫೈಲ್

ಮೊದಲು, sample.log ಎಂಬ ಒಂದು ಫೈಲ್ ಅನ್ನು ರಚಿಸಿ ಮತ್ತು ಅದರಲ್ಲಿ ಈ ಕೆಳಗಿನ ಲೈನ್‌ಗಳನ್ನು ಹಾಕಿ. ಇದು ಅಪಾಚೆ ವೆಬ್ ಸರ್ವರ್‌ನ ಸಾಮಾನ್ಯ ಲಾಗ್ ಫಾರ್ಮ್ಯಾಟ್ ಅನ್ನು ಹೋಲುತ್ತದೆ.

sample.log:

127.0.0.1 - - [23/Dec/2025:10:30:01 +0000] "GET /index.html HTTP/1.1" 200 150
192.168.1.1 - user1 [23/Dec/2025:10:31:15 +0000] "GET /about.html HTTP/1.1" 200 250
127.0.0.1 - - [23/Dec/2025:10:32:05 +0000] "POST /login HTTP/1.1" 302 0
192.168.1.2 - user2 [23/Dec/2025:10:33:00 +0000] "GET /images/logo.png HTTP/1.1" 200 5500
192.168.1.1 - user1 [23/Dec/2025:10:34:10 +0000] "GET /not-found.html HTTP/1.1" 404 300
127.0.0.1 - - [23/Dec/2025:10:35:00 +0000] "GET /index.html HTTP/1.1" 200 150

ಕೋಡ್

import re
from collections import Counter


def parse_log_file(log_file_path):
    """ಲಾಗ್ ಫೈಲ್ ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಿ, ಡೇಟಾವನ್ನು ಹೊರತೆಗೆಯುತ್ತದೆ."""

    # Apache Common Log Format ಗಾಗಿ Regex ಪ್ಯಾಟರ್ನ್
    # ನಾವು IP, ದಿನಾಂಕ, HTTP ಮೆಥಡ್, URL, ಮತ್ತು ಸ್ಟೇಟಸ್ ಕೋಡ್ ಅನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡುತ್ತೇವೆ.
    log_pattern = re.compile(
        r'^(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # IP ವಿಳಾಸ
        r'.*?'  # ಮಧ್ಯದ ಭಾಗವನ್ನು ಸ್ಕಿಪ್ ಮಾಡಿ
        r'\[(?P<datetime>.*?)\]'  # ದಿನಾಂಕ ಮತ್ತು ಸಮಯ
        r'\s"'  # ಸ್ಪೇಸ್ ಮತ್ತು ಡಬಲ್ ಕೋಟ್
        r'(?P<method>GET|POST|PUT|DELETE|HEAD)'  # HTTP ಮೆಥಡ್
        r'\s(?P<url>.*?)\s'  # URL
        r'HTTP/\d\.\d"\s'  # HTTP ಆವೃತ್ತಿ
        r'(?P<status>\d{3})'  # ಸ್ಟೇಟಸ್ ಕೋಡ್ (3 ಅಂಕಿಗಳು)
        r'.*$'  # ಲೈನ್‌ನ ಉಳಿದ ಭಾಗ
    )

    parsed_logs = []
    try:
        with open(log_file_path, 'r') as file:
            for line in file:
                match = log_pattern.match(line)
                if match:
                    # ಮ್ಯಾಚ್ ಆದ ಡೇಟಾವನ್ನು ಡಿಕ್ಷನರಿಯಾಗಿ ಪರಿವರ್ತಿಸುವುದು
                    log_data = match.groupdict()
                    parsed_logs.append(log_data)
    except FileNotFoundError:
        print(f"Error: '{log_file_path}' ಫೈಲ್ ಕಂಡುಬಂದಿಲ್ಲ.")
        return None

    return parsed_logs


def generate_report(logs):
    """ಪಾರ್ಸ್ ಮಾಡಿದ ಲಾಗ್‌ಗಳಿಂದ ಸಾರಾಂಶ ವರದಿಯನ್ನು ರಚಿಸುತ್ತದೆ."""
    if not logs:
        print("ಪಾರ್ಸ್ ಮಾಡಲು ಯಾವುದೇ ಲಾಗ್ ಎಂಟ್ರಿಗಳು ಕಂಡುಬಂದಿಲ್ಲ.")
        return

    print("\n--- ಲಾಗ್ ವಿಶ್ಲೇಷಣೆ ವರದಿ ---")

    # IP ವಿಳಾಸಗಳ ಎಣಿಕೆ
    ip_counter = Counter(log['ip'] for log in logs)
    print("\nಟಾಪ್ 5 IP ವಿಳಾಸಗಳು:")
    for ip, count in ip_counter.most_common(5):
        print(f"- {ip}: {count} ವಿನಂತಿಗಳು")

    # ಸ್ಟೇಟಸ್ ಕೋಡ್‌ಗಳ ಎಣಿಕೆ
    status_counter = Counter(log['status'] for log in logs)
    print("\nಸ್ಟೇಟಸ್ ಕೋಡ್‌ಗಳ ಸಾರಾಂಶ:")
    for status, count in status_counter.items():
        print(f"- ಕೋಡ್ {status}: {count} ಬಾರಿ")

    # ಅತಿ ಹೆಚ್ಚು ವಿನಂತಿಸಲಾದ URL ಗಳು
    url_counter = Counter(log['url'] for log in logs)
    print("\nಟಾಪ್ 5 ವಿನಂತಿಸಲಾದ URL ಗಳು:")
    for url, count in url_counter.most_common(5):
        print(f"- {url}: {count} ಬಾರಿ")

    print("\n--------------------------")


def main():
    """ಮುಖ್ಯ ಫಂಕ್ಷನ್."""
    log_file = "sample.log"
    parsed_data = parse_log_file(log_file)

    if parsed_data:
        generate_report(parsed_data)


if __name__ == "__main__":
    main()

ವಿವರಣೆ

  1. Regex ಪ್ಯಾಟರ್ನ್:
    • re.compile(): Regex ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಪದೇ ಪದೇ ಬಳಸುವುದಾದರೆ, ಅದನ್ನು ಕಂಪೈಲ್ ಮಾಡುವುದು ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.
    • (?P<name>...): ಇದು ಒಂದು "ನೇಮ್ಡ್ ಗ್ರೂಪ್". ಇದು ಮ್ಯಾಚ್ ಆದ ಭಾಗವನ್ನು ಕೇವಲ ಇಂಡೆಕ್ಸ್ ಮೂಲಕವಲ್ಲದೆ, ಹೆಸರಿನ ಮೂಲಕವೂ ಆಕ್ಸೆಸ್ ಮಾಡಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.
    • ^...$: ^ ಲೈನ್‌ನ ಆರಂಭವನ್ನು ಮತ್ತು $ ಲೈನ್‌ನ ಅಂತ್ಯವನ್ನು ಸೂಚಿಸುತ್ತದೆ.
    • \d{1,3}: 1 ರಿಂದ 3 ಅಂಕಿಗಳನ್ನು (digits) ಹುಡುಕುತ್ತದೆ.
    • .*?: ಇದು ನಾನ್-ಗ್ರೀಡಿ ಮ್ಯಾಚ್. ಸಾಧ್ಯವಾದಷ್ಟು ಕಡಿಮೆ ಅಕ್ಷರಗಳನ್ನು ಮ್ಯಾಚ್ ಮಾಡುತ್ತದೆ.
    • \[ ಮತ್ತು \]: [ ಮತ್ತು ] ವಿಶೇಷ ಅಕ್ಷರಗಳಾಗಿರುವುದರಿಂದ, ಅವುಗಳನ್ನು ಅಕ್ಷರಶಃ ಮ್ಯಾಚ್ ಮಾಡಲು ನಾವು ಅವುಗಳ ಮುಂದೆ ಬ್ಯಾಕ್‌ಸ್ಲ್ಯಾಶ್ (\) ಹಾಕಬೇಕು.
  2. parse_log_file ಫಂಕ್ಷನ್:
    • ಲಾಗ್ ಫೈಲ್‌ನ ಪ್ರತಿಯೊಂದು ಲೈನ್ ಅನ್ನು ಓದಿ, ಅದರ ಮೇಲೆ log_pattern.match() ಅನ್ನು ಅನ್ವಯಿಸುತ್ತದೆ.
    • match.groupdict(): ನೇಮ್ಡ್ ಗ್ರೂಪ್‌ಗಳನ್ನು ಬಳಸಿ, ಈ ಮೆಥಡ್ ಮ್ಯಾಚ್ ಆದ ಎಲ್ಲಾ ಭಾಗಗಳನ್ನು ಒಂದು ಡಿಕ್ಷನರಿಯಾಗಿ ( {'ip': '127.0.0.1', 'datetime': '...', ...}) ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
    • ಈ ಡಿಕ್ಷನರಿಗಳನ್ನು parsed_logs ಲಿಸ್ಟ್‌ಗೆ ಸೇರಿಸಲಾಗುತ್ತದೆ.
  3. generate_report ಫಂಕ್ಷನ್:
    • from collections import Counter: Counter ಎನ್ನುವುದು ಒಂದು ವಿಶೇಷ ಡಿಕ್ಷನರಿ. ಇದು ಲಿಸ್ಟ್‌ನಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು ಐಟಂ ಎಷ್ಟು ಬಾರಿ ಪುನರಾವರ್ತನೆಯಾಗಿದೆ ಎಂದು ಸುಲಭವಾಗಿ ಎಣಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ.
    • ip_counter = Counter(log['ip'] for log in logs): ಇದು ಒಂದು ಜನರೇಟರ್ ಎಕ್ಸ್‌ಪ್ರೆಶನ್ ಬಳಸಿ, ಎಲ್ಲಾ ಲಾಗ್‌ಗಳಿಂದ IP ವಿಳಾಸಗಳನ್ನು ತೆಗೆದುಕೊಂಡು, Counter ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ರಚಿಸುತ್ತ���ೆ.
    • .most_common(5): Counter ನ ಈ ಮೆಥಡ್, ಅತಿ ಹೆಚ್ಚು ಬಾರಿ ಪುನರಾವರ್ತನೆಯಾದ 5 ಐಟಂಗಳನ್ನು ಮತ್ತು ಅವುಗಳ ಎಣಿಕೆಯನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
    • ಈ ಫಂಕ್ಷನ್ IP ವಿಳಾಸಗಳು, ಸ್ಟೇಟಸ್ ಕೋಡ್‌ಗಳು, ಮತ್ತು URL ಗಳ ಸಾರಾಂಶವನ್ನು ಪ್ರಿಂಟ್ ಮಾಡುತ್ತದೆ.